在给出新的道具值时,如何强制子组件重新渲染?

时间:2017-08-12 18:53:07

标签: reactjs

我尝试过这种模式。

ParentComponent
...
render(
return <ChildComponent newProps="newPropsValue />)

ChildComponent
...
ComponentWillReceiveProps{
this.setState({"propsKey": "newPropsValue"})
}

据我所知,初始组件渲染是由props更改触发的,并且由于setState是异步的(由于某种原因),因此在第一次传递时不会使用新状态更新进行渲染。

然而,我不明白为什么当它最终决定更新状态时,它不会重新渲染组件。我认为由setState引起的状态更改总是触发重新呈现。

所以最后我有一个组件在状态实际改变之前无用地重新渲染,然后在/ if(?)状态更新时什么都不做。我根本不明白这种行为。

2 个答案:

答案 0 :(得分:0)

setState会触发componentUdpate - &gt; componentWillUpdate - &gt; renderprops更改将在此链之前触发componentWillReceiveProps。您可以在此处查看有关React lifecycle的图片。您可以在Reactprops上看到state行为的不同之处。

所以:

  

然而,我不明白为什么当它最终决定更新状态时,它不会重新渲染组件。

state更新setState将触发render功能(重新渲染)。 props也会触发render

关注您的代码:

  1. componentWillReceiveProps
    • this.props.newProps="newPropsValue"
    • this.state.propsKey="newPropsValue"
  2. render:如上所述,没有任何改变。
  3. 如果childComponent设置propsKey setState onClickonChangesetState({propsKey: "anotherValue"}) ...)的任何事件。假设render。然后,this.state.propsKey="anotherValuethis.props.newProps="newPropsValue"
  4. 将再次触发childComponent

    现在让我们在props内更新您的parentComponent newProps="latestPropsValue",假设componentWillReceiveProps

    1. this.props.newProps="latestPropsValue"之前:
      • this.state.propsKey="anotherValue"
      • componentWillReceiveProps
    2. this.props.newProps="latestPropsValue"之后:
      • this.state.propsKey="latestPropsValue"
      • render
    3.   

      如果给出新的道具值,我如何强制子组件重新渲染?

      如果您的state正在使用setState,那么render会在props内。如果您在render内使用Droid Arabic Naskh,它也会相应更新

答案 1 :(得分:0)

我已经找到了使用 key 属性的不错的解决方案。如果我们更改了子组件或React组件的某些部分的 key 属性,它将完全重新渲染。当您需要根据属性或状态重新渲染React Component的某些部分或重新渲染子组件时,它将使用它。这是一个例子。我将重新渲染整个组件。

import React, { useState, useEffect } from "react";
import { PrEditInput } from "./shared";

const BucketInput = ({ bucketPrice = [], handleBucketsUpdate, mood }) => {
  const data = Array.isArray(bucketPrice) ? bucketPrice : [];
  const [state, setState] = useState(Date.now());
  useEffect(() => {
    setState(Date.now());
  }, [mood, bucketPrice]);
  return (
    <span key={state}>
      {data.map((item) => (
        <PrEditInput
          key={item.id}
          label={item?.bucket?.name}
          name={item.bucketId}
          defaultValue={item.price}
          onChange={handleBucketsUpdate}
          mood={mood}
        />
      ))}
    </span>
  );
};

export default BucketInput;