React TS. Объединить 2 и более компоненты выполняющую одну и ту же задачу (но типы даных и параметры разные) в одну универсальную
React TS.
Объединить 2 и более компоненты выполняющую одну и ту же задачу (но типы даных и параметры разные) в одну универсальную.
Подброно:
Нужно декомпозировать компоненты в 1. Но проблема в том, что list из store имеет разные данные, функции (там есть и общие но у них тоже разные типы и параметры ) и тип данных в 1-ой это quiz.list с IQuizRow[] , а во 2-ой это quiz_session.list с типом IQuizSessionRow[].
Но по сути эти компоненты выполняют один алгоритм. Отображают список.
Пробовал в props прокидывать list: any[] и store: any. Но тогда это немного не правильно с точки зрения TS. нужно чтобы точно знал что есть в props.
Также не подходит вариант с общим типом который будет равен типам props. так так придется каждый раз добавлять туда новый тип если нужен новый список
с другими данными, и если там будет 2+ типов это по сути тот же any так что опять нарушаем принцип TS.
- Это список викторин
const QiuzList = observer(() => {
const {store} = useContext(Context);
const navigate = useNavigate();
const {t} = useTranslation();
const {height} = useWindowSize()
useEffect(() => {
store.quiz.list.loader.set(true)
return () => store.quiz.list.loader.set(true)
}, [])
const [limit, setLimit] = useState<number>(5);
const [offset, setOffset] = useState<number>(0);
const [list, setList] = useState<IQuizRow[]>([]);
useEffect(() => {
reload()
}, [offset])
const reload = () => {
store.quiz.list.request({limit, offset}).then(r => {
console.log(r)
setList([...list, ...store.quiz.list.get().results])
})
}
return <div>...</div>
});
- Это список сессий
const QiuzSessionList = observer(() => {
const {store} = useContext(Context);
const navigate = useNavigate();
const {t} = useTranslation();
const {height} = useWindowSize()
useEffect(() => {
store.quiz_session.list.loader.set(true)
return () => store.quiz_session.list.loader.set(true)
}, [])
const [limit, setLimit] = useState<number>(5);
const [offset, setOffset] = useState<number>(0);
const [list, setList] = useState<IQuizSessionRow[]>([]);
useEffect(() => {
reload()
}, [offset])
const reload = () => {
store.quiz_session.list.request({limit, offset}).then(r => {
console.log(r)
setList([...list, ...store.quiz_session.list.get().results])
})
}
return <div>...</div>
})
Какая же мне нужна компонента примерно. Дальше псевдокод:
type Props = {
props_list: ТИП КОТОРЫЙ РАВЕН YOUR_LIST_STORE из store со всеми достпуными в ней функциями,
row: YOUR_LIST_ROW_TYPE,
}
const List = observer(({props_list, row}:Props) => {
const {store} = useContext(Context);
useEffect(() => {
// вот тут я вроде вызываю функции,
// но я точно не могу быть уверен,
// что такая функия есть. так как type any
props_list.loader.set(true)
return () => props_list.loader.set(true)
}, [])
const [limit, setLimit] = useState<number>(5);
const [offset, setOffset] = useState<number>(0);
const [virtual_list, setVirtualList] = useState<YOUR_LIST_ROW_TYPE[]>([]);
useEffect(() => {
reload()
}, [offset])
const reload = () => {
// вот тут я вроде вызываю функции,
// но я точно не могу быть уверен,
// что такая функия есть. так как type any
props_list.request({limit, offset}).then(r => {
console.log(r)
setVirtualList([...virtual_list, ...props_list.get().results])
})
}
return <div>...</div>
})
Вот так не подойдет с any т.к могут быть ошибки в реалтайме
и опять же, нужно, чтобы не было возможности вызывать любые функции:
type Props = {
props_list: any,
row: any,
}
const List = observer(({props_list, row}:Props) => {
useEffect(() => {
props_list.loader.set(true)
return () => props_list.loader.set(true)
}, [])
const [limit, setLimit] = useState<number>(5);
const [offset, setOffset] = useState<number>(0);
const [virtual_list, setVirtualList] = useState<typeof row[]>([]);
useEffect(() => {
reload()
}, [offset])
const reload = () => {
props_list.request({limit, offset}).then((r: any) => {
console.log(r)
setVirtualList([...virtual_list, ...props_list.get().results])
})
}
return <div>...</div>
})
Ответы (1 шт):
type PartOne = {
type: '1',
list: string
}
type PartTwo = {
type: '2',
list: Array<string>
}
type MultipleTypes = PartOne | PartTwo
const ComponentMultipleTypes = (props: MultipleTypes) => {
return null;
}
<ComponentMultipleTypes type="1" list={["1231231"]} /> - error
<ComponentMultipleTypes type="1" list={"1231231"} /> - ok
<ComponentMultipleTypes type="2" list={["1231231"]} /> - ok
<ComponentMultipleTypes type="2" list={"1231231"} /> - error