简体   繁体   English

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

[英]Child component not updating with updates state via Parent props

I have a parent component from where I am passing a callback function handleProjectStagesSave and some data as props to child component. 我有一个父组件,从那里我传递了一个回调函数handleProjectStagesSave和一些数据作为对子组件的支持。 In my child component, I am accessing the props and storing the props object as a whole to the state using useState . 在子组件中,我正在访问props并使用useStateprops对象作为一个整体存储到状态。

Parent component: 父组件:

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

Now, the child component passes the callback function to it's own child component CriteriaScores which basically passes some data and sends it back all the way up to the parent. 现在,子组件将回调函数传递给它自己的子组件CriteriaScores ,该子组件基本上传递一些数据并将其一直发送回父级。

Child component: 子组件:

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

It works fine and I get the data and store update the state setProjectStages(projectStages); 它工作正常,我获取数据并存储更新状态setProjectStages(projectStages); in parent component. 在父组件中。 Now, I expect the child component to have the updated state data immediately. 现在,我希望子组件立即具有更新的状态数据。 However, what I saw in React dev tools is that, after updating the state, I update the props in the child component manually, then the state changes are reflected in the Child component. 但是,我在React开发工具中看到的是,在更新状态之后,我手动更新了子组件中的道具,然后状态更改反映在子组件中。 Any idea what is wrong? 知道有什么问题吗? Please let me know if I can clarify more on this. 请让我知道是否可以进一步说明。

Update-1: 更新1:

Instead of mutating the state directly I tried something like below but got same result. 我没有直接改变状态,而是尝试了如下所示的方法,但是得到了相同的结果。

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

Update-2: 更新2:

Also tried below approach but it did not work. 还尝试了以下方法,但没有用。

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

projectStages is a state variable, and you are mutating it directly. projectStages是一个状态变量,您可以直接对其进行变异。

projectStages.someProperty = val; 

The recommended way of doing this is as follows: 推荐的方法如下:

setProjectStages(...projectStages, someProperty : val)

When you use setProjectStages react will re-render, and the most recent state variable will be passed to the child component. 使用setProjectStages反应将重新呈现,并且最新的状态变量将传递到子组件。

In addition to the answer provided by @user9408899, I would add that the child component does not need to store its props in state. 除了@ user9408899提供的答案外,我还要补充一点,子组件不需要以状态存储其道具。 I would change it to: 我将其更改为:

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

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

This worked: 这工作:

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

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

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