#reactjs #react-redux #react-hooks
Вопрос:
Я использую крючки для получения данных из бэкенда. api дает 2 разных результата на основе параметра. На экране 1 я вызываю крючок без параметров и получаю результаты. На экране 2 я хочу вызвать тот же крючок, но с параметром для того же API.
Например, когда я нахожусь на экране 1, я получаю список сотрудников (скажем, 10 записей). Теперь, когда я перехожу на экран2 и вызываю крючок с параметром, я ожидаю, что api будет выполнен и даст мне, скажем, 20 записей. Но данные ответа от вызова api уже доступны на employees
экране 1, поэтому отправка больше не выполняется. Смотрите строку ниже.
if (typeof employees === 'undefined' amp;amp; !loader)
Чтобы преодолеть эту проблему, я подумал об использовании флага, передаваемого крючкам, когда я нахожусь на экране 2, и вызываю api с помощью param. Но это заканчивается бесконечным циклом. Есть идеи, как решить эту проблему?
Вот мой крючок:
const useEmployees = param => {
const dispatch = useDispatch()
const loader = useSelector(getLoader)
// Fetch all employees
const employees = useSelector(getEmpList)
useEffect(() => {
if (typeof employees === 'undefined' amp;amp; !loader) {
dispatch(getEmployees(param))
}
}, [param, employees, dispatch, loader])
return { loader, employees }
}
export default useEmployees
Ответ №1:
Не задаваясь вопросом, почему [param, employees, dispatch, loader]
ваш список депов или почему диспетчер еще не решил эту проблему за вас, решение, которое всегда доступно, — это просто использовать ссылку.
const paramRef = React.useRef(param);
// then in the useEffect:
useEffect(() => {
let paramChanged = false;
if (param !== paramRef.current) {
paramRef.current = param; // update the compare value
paramChanged = true;
}
if (paramChanged ...etc) {
// ...
}, [ ... ])
Комментарии:
1. Я попробовал это решение, оно снова попадает в бесконечный цикл 🙁
2. Ты записываешь свои
param
? Если нет, вы можете запустить бесконечный цикл повторного рендеринга. React предупредит вас об этом.3. Нет, я не занимаюсь useMemo. Требуется ли это?
4. Что ж, очевидный ответ- да , но, вероятно, хорошо, что вы понимаете почему. Для этого есть много документации reactjs.org/docs/hooks-reference.html#usememo и я обнаружил, что как только это «щелкает» в вашей голове, подобные проблемы становятся легко решаемыми. Если вы занимаетесь асинхронными вещами, вам понадобится хорошее понимание запоминания.
5. Вот что я делаю:
useEffect(() => { let paramChanged = false if (param !== paramRef.current) { paramRef.current = param // update the compare value paramChanged = true } if (paramChanged amp;amp; !loadingStatus) { dispatch(getEmployees(param)) paramChanged = false } else if (typeof employees === 'undefined' amp;amp; !loadingStatus) { dispatch(getEmployees(param)) //here param is undefined 'cos the call does not need a param } }, [param, employees, dispatch, loadingStatus])