【问题标题】:Child component not updating with updates state via Parent props子组件没有更新到父道具的更新状态
【发布时间】:2019-08-20 18:17:28
【问题描述】:

我有一个父组件,我从中传递一个回调函数handleProjectStagesSave 和一些数据作为子组件的道具。在我的子组件中,我正在访问props 并将props 对象作为一个整体存储到使用useState 的状态中。

父组件:

function ProjectStages(props) {
    const [projectStages, setProjectStages] = React.useState(null);

    useEffect(() => {
          ProjectAPI.getProjectStages().then((response) => {
            setProjectStages(response);
          });
    }, []);

    //this function is passed as prop to child component. child component send data through parameters back to parent
    function handleProjectStagesSave(val){     
      projectStages.someProperty = val;  //modifying state property here and updating the state below
      setProjectStages(projectStages);
    }

    if(projectStages === null){
      return (<Loader/>);
    }

    return (
      <div>
        {(() => {
           //loop through state data and pass props to child component
          return projectStages.phases.map((stage) => {
            return (
                <ProjectStageTile criterias={stage.criterias} stagesSave={handleProjectStagesSave}/>
            );
          });
        })()}
      </div>
    );
}

现在,子组件将回调函数传递给它自己的子组件CriteriaScores,它基本上会传递一些数据并将其一直发送回父组件。

子组件:

function ProjectStageTile(props){
    const [projectStageTileState, setProjectStageTileState] = React.useState(props);

    return projectStageTileState.criterias.map((criteria) => {

        return(
            <div>
                <div>
                    {criteria.selectedScore}
                </div>
                <CriteriaScores stagesSave={projectStageTileState.stagesSave} />
            </div>
        );
    });
}

它工作正常,我获取数据并在父组件中存储更新状态setProjectStages(projectStages);。现在,我希望子组件立即拥有更新的状态数据。但是,我在 React 开发工具中看到的是,在更新状态后,我手动更新了子组件中的 props,然后状态的变化反映在了子组件中。知道有什么问题吗?请让我知道是否可以对此进行更多说明。

更新 1:

我没有直接改变状态,而是尝试了类似下面的方法,但得到了相同的结果。

projectStages.phases.filter((phase) => (phase.gdfatStage === "bid"))[0].criterias
      .filter((criteria) => (criteria.criteriaId === val.split(' ')[1]))[0].selectedScore = val.split(' ')[2];
let newProjectStages = projectStages;
setProjectStages(newProjectStages);

更新 2:

也尝试了以下方法,但没有成功。

let newProjectStages = projectStages;

newProjectStages.phases.filter((phase) => (phase.gdfatStage === "bid"))[0].criterias
.filter((criteria) => (criteria.criteriaId === val.split(' ')[1]))[0].selectedScore = val.split(' ')[2];

setProjectStages(newProjectStages);

【问题讨论】:

    标签: javascript reactjs react-hooks


    【解决方案1】:

    projectStages 是一个状态变量,你直接修改它。

    projectStages.someProperty = val; 
    

    推荐的做法如下:

    setProjectStages(...projectStages, someProperty : val)
    

    当你使用setProjectStages时,react 会重新渲染,并将最近的状态变量传递给子组件。

    【讨论】:

    • 嗨。根据您的回答,我更新了问题并添加了更多详细信息。请检查。
    • @SouvikGhosh filter 函数返回变量,不会更改调用它的 Array 的内容。因此,您需要使用一个临时变量来存储从filter function 返回的数据。像这样: const tempVar = projectStages.phases.filter((phase) =>..... 然后,使用该变量来更新状态,如下所示: setProjectStages(...projectStages, phase: tempVar )。
    • 这不起作用。如果你看到了,我正在像这样改变状态属性:.......selectedScore = val.split(' ')[2];,然后将整个状态对象存储到一个新的临时变量 newProjectStages 并更新状态:setProjectStages(newProjectStages);
    • 用一些更新编辑了我的问题。请检查。
    • @SouvikGhosh 好的,我想你明白了。正如我在回答中所说,变异状态导致了这个错误。
    【解决方案2】:

    这行得通:

    const newProjectStages = Object.assign({}, projectStages); //this is important
    
    newProjectStages.phases.filter((phase) => (phase.gdfatStage === "bid"))[0].criterias
    .filter((criteria) => (criteria.criteriaId === val.split(' ')[1]))[0].selectedScore = val.split(' ')[2];
    
    setProjectStages(newProjectStages);
    

    【讨论】:

      【解决方案3】:

      除了@user9408899 提供的答案之外,我还要补充一点,子组件不需要将其道具存储在状态中。我会将其更改为:

      function ProjectStageTile(props){
          const {criteria, stagesSave} = props;
      
          return criterias.map((criteria) => {
              return(
                  <div>
                      <div>
                          {criteria.selectedScore}
                      </div>
                      <CriteriaScores stagesSave={stagesSave} />
                  </div>
              );
          });
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-03-25
        • 2020-07-18
        • 1970-01-01
        • 2021-03-02
        • 2019-04-17
        • 1970-01-01
        • 2020-08-07
        • 1970-01-01
        相关资源
        最近更新 更多