Chris
Chris

Reputation: 155

React re-write componentWillReceiveProps in useEffect

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?

Upvotes: 2

Views: 8498

Answers (4)

Dennis Vash
Dennis Vash

Reputation: 53874

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 ...
};

Upvotes: 3

Mohamed Ramrami
Mohamed Ramrami

Reputation: 12691

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

Upvotes: 3

Avanthika
Avanthika

Reputation: 4182

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.
}

Upvotes: 6

Cheepo2109
Cheepo2109

Reputation: 47

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.

Upvotes: 0

Related Questions