use object in useEffect 2nd param without having to stringify it to JSON

后端 未结 3 1732
小蘑菇
小蘑菇 2020-12-30 03:13

In JS two objects are not equals.

const a = {}, b = {};
console.log(a === b);

So I can\'t use an object in useEffect (React ho

3条回答
  •  [愿得一人]
    2020-12-30 03:33

    You could create a custom hook that keeps track of the previous dependency array in a ref and compares the objects with e.g. Lodash isEqual and only runs the provided function if they are not equal.

    Example

    const { useState, useEffect, useRef } = React;
    const { isEqual } = _;
    
    function useDeepEffect(fn, deps) {
      const isFirst = useRef(true);
      const prevDeps = useRef(deps);
    
      useEffect(() => {
        const isFirstEffect = isFirst.current;
        const isSame = prevDeps.current.every((obj, index) =>
          isEqual(obj, deps[index])
        );
    
        isFirst.current = false;
        prevDeps.current = deps;
    
        if (isFirstEffect || !isSame) {
          return fn();
        }
      }, deps);
    }
    
    function App() {
      const [state, setState] = useState({ foo: "foo" });
    
      useEffect(() => {
        setTimeout(() => setState({ foo: "foo" }), 1000);
        setTimeout(() => setState({ foo: "bar" }), 2000);
      }, []);
    
      useDeepEffect(() => {
        console.log("State changed!");
      }, [state]);
    
      return 
    {JSON.stringify(state)}
    ; } ReactDOM.render(, document.getElementById("root"));
    
    
    
    
    

提交回复
热议问题