2

I'm trying to convert UNSAFE_componentWillReceiveProps into a hook. Below is the logic for using CWRP.

UNSAFE_componentWillReceiveProps(nextProps){
  if (this.props.val1 !== nextProps.val1 && this.props.val2 !== nextProps.val2) {
    // do something
  }
}

Is there any way I can tell hook to call effect only when val1 & val2 changes.

useEffect(() => {
  // do something only when both inputs change 
}, [val1, val2])
Faiyaz Shaikh
  • 127
  • 3
  • 10
  • Possible Duplicate of [How to compare oldValues and newValues on React Hooks useEffect?](https://stackoverflow.com/questions/53446020/how-to-compare-oldvalues-and-newvalues-on-react-hooks-useeffect/53446665#53446665) – Shubham Khatri Feb 15 '19 at 05:59
  • Did any of the answers work for you? Consider [accepting one of them](https://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work#answer-5235) if that's the case. – Tholle Feb 15 '19 at 22:14

2 Answers2

4

`I guess you could use a custom hook as mentioned in react documents:

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

function MyComponent({val1, val2}) {
    let val1Prev = usePrevious(val1);
    let val2Prev = usePrevious(val2);
    useEffect(() => {
        if(val1Prev !== val1 || val2Prev !== val2) {
            // do whatever you want
        }
    })
}

Also, make attention to this sentence from react documents:

It’s possible that in the future React will provide a usePrevious Hook out of the box since it’s a relatively common use case.

Eddie Cooro
  • 1,676
  • 14
  • 18
1

You could use the useRef hook to store the props of the last time the effect was run and compare against that.

Example

const { useEffect, useRef } = React;

function MyComponent({ val1, val2 }) {
  const lastProps = useRef({ val1, val2 });
  useEffect(
    () => {
      if (lastProps.current.val1 !== val1 && lastProps.current.val2 !== val2) {
        console.log("Both changed!");
      }

      lastProps.current = { val1, val2 };
    },
    [val1, val2]
  );

  return <div> {val1} {val2} </div>;
}

class App extends React.Component {
  state = { val1: 1, val2: 1 };

  componentDidMount() {
    setTimeout(() => this.setState({ val1: 2 }), 1000);
    setTimeout(() => this.setState({ val2: 2 }), 2000);
    setTimeout(() => this.setState({ val1: 3, val2: 3 }), 3000);
  }

  render() {
    const { val1, val2 } = this.state;
    return <MyComponent val1={val1} val2={val2} />;
  }
}

ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://unpkg.com/react@16/umd/react.development.js" ></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" ></script>

<div id="root"></div>
Tholle
  • 108,070
  • 19
  • 198
  • 189