简体   繁体   English

React 组件在 useEffect 后不重新渲染(使用了依赖数组)

[英]React component does not rerender after useEffect (dependency array used)

I have an object state priceRanges in component A, which i initialize with a key and a value:我在组件 A 中有一个 object state priceRanges ,我用一个键和一个值初始化它:

const [priceRanges, setPriceRanges] = useState({
        [randomId]: {
            "price": 0,
            "quantity": 0
        }
    })

And then pass it through props to component B:然后通过 props 将其传递给组件 B:

<ComponentB pricesRanges={pricesRanges} ...props />

The problem is that in Component B, I am converting this object into an array on useEffect:问题是在组件 B 中,我将这个 object 转换为 useEffect 上的数组:

React.useEffect(() => {
        const getArrayData = () => {
            const keys = Object.keys(priceRanges)
            keys.map(key => {
                console.log(priceRanges[key]["price"])
                priceRangesArray.push({
                    id: key,
                    price: priceRanges[key]["price"] ? priceRanges[key]["price"] : 0,
                    quantity: priceRanges[key]["quantity"] ? priceRanges[key]["quantity"] : 0
                })
            })
        }
        getArrayData()
    }, [priceRanges])

But the component does not rerender after the useEffect has run.但是在 useEffect 运行后组件不会重新渲染。 As such, the component does not render the initial state that pricesRanges was initialized with.因此,该组件不会呈现初始化价格范围的初始pricesRanges To test this, I did this:为了测试这一点,我这样做了:

{priceRangesArray.length > 0 ? 
            (priceRangesArray.map(quantityAndPrice => {
                return (
                    <div className="flex" key={quantityAndPrice.id}>
                        {console.log("I AM RENDERING")}
                        <input
                            ...props
                        />
                        <input
                            ...props
                        />
                    </div>
                )
            })) :<p>Hello</p>}

Which always renders Hello on mount.它总是在安装时呈现 Hello。 How can I tackle this?我该如何解决这个问题? Thanks you !谢谢 !

The only way to cause a rerender is to set state.导致重新渲染的唯一方法是设置 state。 Mutating an array during a useEffect will not cause a rerender.在 useEffect 期间改变数组不会导致重新渲染。 So you could fix this by adding a state variable, and then setting state once you've calculated the array.因此,您可以通过添加 state 变量来解决此问题,然后在计算完数组后设置 state。

However, i think that's not the right approach here.但是,我认为这不是正确的方法。 Your array is derived data: it's directly based on what's in priceRanges , and you don't want it to ever deviate from that.您的数组是派生数据:它直接基于priceRanges中的内容,您不希望它偏离该值。 So for this, i would calculate the value in line during rendering the component:因此,为此,我将在渲染组件期间在线计算值:

const Example = ({ priceRanges }) => {
  const keys = Object.keys(priceRanges);
  const priceRangesArray = keys.map((key) => {
    return {
      id: key,
      price: priceRanges[key]["price"] ? priceRanges[key]["price"] : 0,
      quantity: priceRanges[key]["quantity"] ? priceRanges[key]["quantity"] : 0,
    };
  });

  // ...rest of the component
}

If performance is a concern, you can wrap this in useMemo to skip the calculation if priceRanges has not changed.如果性能是一个问题,如果priceRanges没有更改,您可以将其包装在useMemo中以跳过计算。

const Example = ({ priceRanges }) => {
  const priceRangesArray = useMemo(() => {
    const keys = Object.keys(priceRanges);
    return keys.map((key) => {
      return {
        id: key,
        price: priceRanges[key]["price"] ? priceRanges[key]["price"] : 0,
        quantity: priceRanges[key]["quantity"] ? priceRanges[key]["quantity"] : 0,
      };
    });
  }, [priceRanges]);

  // ... rest of the component
};

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

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