2

So I am re-writing a component with hooks, and I ran into an interesting challenge, I need to mimick some old behaviour of componentWillReceiveProps with the useEffect hook.

My old code looks like:

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);

  }
}

You see, I am initiating a const based on nextProps, then in the if statement i do a couple checks based on that nextVal, now, I know that we can specify a second argument to useEffect to run it only when a prop changes, but what about those checks, how can i implement something similar to nextProps?

Chris
  • 155
  • 4
  • 11

4 Answers4

6

You can create custom hook:

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

and get it used in 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.
}
Avanthika
  • 3,984
  • 1
  • 12
  • 19
3

You can use useRef to save the prev props, and use useEffect to run when props change, something like this :

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>)
}
Mohamed Ramrami
  • 12,026
  • 4
  • 33
  • 49
3

With the current logic, you want to fire a side-effect only on lateMinutes[${bookingId}].value change:

const Component = props => {
  useEffect(() => {
    console.log('prop lateMinutes changed');
    // ...
  }, [props[`lateMinutes[${bookingId}].value`]);
  return ...
};
Dennis Vash
  • 50,196
  • 9
  • 100
  • 118
0

You don’t need hooks to handle prerender lifecycle. Just put the things in the functional component before returning JSX as the function itself is equivalent to render method of class based component.

Cheepo2109
  • 37
  • 6