简体   繁体   English

在 useEffect 内反应钩子 updateState

[英]react hooks updateState inside useEffect

I want to update my component's state inside of useEffect but compare and update the state only if the object has changed.我想在useEffect更新我的组件状态,但仅当对象发生更改时才比较和更新状态。

How can I do that?我怎样才能做到这一点?

This is my current code:这是我当前的代码:

const Features = ({ fetchProductFeature, productFeature }) => {
  const [features, setFeatures] = useState([]);

  const usePrevious = value => {
    const ref = useRef();
    useEffect(() => {
      ref.current = value;
    });
    return ref.current;
  };
  const myPreviousState = usePrevious(productFeature);
  useEffect(() => {
    fetchProductFeature();
    if (myPreviousState && !_.isEqual(myPreviousState, productFeature)) {
      let features =
        productFeature &&
        fetchProductFeature.data &&
        fetchProductFeature.data.map(feature => ({
          label: feature,
          value: false
        }));
      setFeatures(features);
    }
  }, [fetchProductFeature, productFeature, myPreviousState]);

  console.log("productFeature", productFeature);

  if (productFeature.loading) return "Loading...";
  if (productFeature.error) return "Error";
  if (productFeature.data) {

    return (
      <ErrorBoundary>
        <Card>
          {'UI CODE HERE'}
        </Card>
      </ErrorBoundary>
    );
  }
  return null;
};

const mapStateToProps = ({ accountsReducer }) => ({
  productFeature: accountsReducer.productFeature
});

const mapDispatchToProps = dispatch => ({
  fetchProductFeature: () => dispatch(fetchProductFeature())
});    
export default connect(mapStateToProps, mapDispatchToProps)(Features);

udeDeepCompare.js udeDeepCompare.js

import { useRef, useEffect } from "react";
import _ from "lodash";

function useDeepEffect(fn, deps) {
  const isFirst = useRef(true);
  const prevDeps = useRef(deps);

  useEffect(() => {
    const isSame = prevDeps.current.every((obj, index) =>
      _.isEqual(obj, deps[index])
    );

    if (isFirst.current || !isSame) {
      fn();
    }

    isFirst.current = false;
    prevDeps.current = deps;
  }, deps);
}

export default useDeepEffect;

Features.js功能.js

useEffect(() => {
    fetchProductFeature();
  }, [fetchProductFeature]);

  useDeepEffect(() => {
    console.log("State changed!");
    let features =
      productFeature.data &&
      productFeature.data.map(feature => ({
        label: feature,
        value: false
      }));
    setFeatures(features);
  }, [productFeature.data]);

You can compare your previous state before setting the state, see the below example您可以在设置状态之前比较之前的状态,请参见下面的示例

    useEffect(() => {
      const fetchAndUpdateState = async () => {
        const data = await api.fetchData();
        setFeatures((prevState) => {
          if(deepCompare(prevState,data) {
            return data;
          }
        })
      }
      fetchAndUpdateState();
    }, [])

Also, I would recommend you to use lodash.isEqual for deep comparison https://lodash.com/docs/#isEqual另外,我建议您使用 lodash.isEqual 进行深度比较https://lodash.com/docs/#isEqual

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM