子组件未通过父项以更新状态更新

时间:2019-08-20 18:17:28

标签: javascript reactjs react-hooks

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

父组件:

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开发工具中看到的是,在更新状态之后,我手动更新了子组件中的道具,然后状态更改反映在子组件中。知道有什么问题吗?请让我知道是否可以进一步说明这一点。

更新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);

3 个答案:

答案 0 :(得分:2)

projectStages是一个状态变量,您可以直接对其进行变异。

projectStages.someProperty = val; 

推荐的方法如下:

setProjectStages(...projectStages, someProperty : val)

当您使用setProjectStages时,react将重新呈现,并且最新的状态变量将传递给子组件。

答案 1 :(得分:1)

这有效:

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);

答案 2 :(得分:0)

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

function ProjectStageTile(props){
    const {criteria, stagesSave} = props;

    return criterias.map((criteria) => {
        return(
            <div>
                <div>
                    {criteria.selectedScore}
                </div>
                <CriteriaScores stagesSave={stagesSave} />
            </div>
        );
    });
}
相关问题