Справочники можно использовать двумя разными способами

#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])