React re-write componentWillReceiveProps in useEffect

Итак, я переписываю компонент с хуками, и я столкнулся с интересной задачей: мне нужно имитировать какое-то старое поведение componentWillReceiveProps с useEffect крючок.

Мой старый код выглядит так:

componentWillReceiveProps(nextProps: Props) {

  const prevLateVal = get(`lateMinutes[${bookingId}].value`, this.props);
  const nextLateVal = get(`lateMinutes[${bookingId}].value`, nextProps); //see here, 
//we use next props

  if (typeof nextLateVal !== 'undefined' && prevLateVal !== nextLateVal) {
    client.connect(bookingId, nextLateVal === null ? 0 : nextLateVal);

  }
}

Видите ли, я начинаю const на основе nextProps, затем в if оператор, я делаю пару проверок на основе этого nextVal, теперь я знаю, что мы можем указать второй аргумент для useEffect запускать его только при изменении опоры, но как насчет этих проверок, как я могу реализовать что-то похожее на nextProps?

4 ответа

Решение

Вы можете создать собственный хук:

function usePrevious(value) {
  const ref = useRef();
  useEffect(() => {
    ref.prevLateVal = value;
  });
  return ref.prevLateVal;
}

и использовать его в useEffect()

const Component = (props) => {
    const currentLateValue = get(`lateMinutes[${bookingId}].value`, props)
    const prevLateVal = usePrevious(currentLateValue);
    useEffect(() => {
        if(prevLateVal !== currentLateValue) {
         // process here
        }
    }, [currentLateValue]) // This will be executed only if currentLateValue changes.
}

С текущей логикой вы хотите запускать побочный эффект только на lateMinutes[${bookingId}].value менять:

const Component = props => {
  useEffect(() => {
    console.log('prop lateMinutes changed');
    // ...
  }, [props[`lateMinutes[${bookingId}].value`]);
  return ...
};

Ты можешь использовать useRef чтобы сохранить предыдущие реквизиты, и используйте useEffect запускать при изменении реквизита, примерно так:

function MyComponent(props) {

  const prevProps = useRef(props);

  useEffect(() => {
    const prevLateVal = get(`lateMinutes[${bookingId}].value`, prevProps.current);
    const nextLateVal = get(`lateMinutes[${bookingId}].value`, props);

    if (typeof nextLateVal !== 'undefined' && prevLateVal !== nextLateVal) {
      client.connect(bookingId, nextLateVal === null ? 0 : nextLateVal);
    }    

    prevProps.current = props;
  }, [props, bookingId]);

  return (<div>...</div>)
}

Вам не нужны хуки для обработки жизненного цикла пререндера. Просто поместите вещи в функциональный компонент перед возвратом JSX, поскольку сама функция эквивалентна методу визуализации компонента на основе класса.

Другие вопросы по тегам