简体   繁体   中英

React : Prop not updated inside of a map function

Edit:Codesandbox here

Here is a simplified version on my parent component:

export default function Parent() {
  // State
  const [status, setStatus] = useState(1);
  const [source, setSource] = useState('https://packagingeurope.com/downloads/7475/download/danone-05.03.20.jpg');
  const [steps, setSteps] = useState([
    {
      title: 'Prediction Initiated',
      value: 1,
      loading: false,
      completed: false,
      active: false,
    },
    {
      title: 'Prediction in Progress',
      value: 2,
      loading: false,
      completed: false,
      active: false,
    },
    {
      title: 'Prediction Finished',
      value: 3,
      loading: false,
      completed: false,
      active: false,
    },
  ]);

useEffect(() => {
    if (status) {
      const newSteps = steps;
      newSteps[status - 1].active = true;
      if (status > 1) {
        newSteps[status - 2].completed = true;
      }
      if (status === 3) {
        newSteps[status - 1].active = false;
        newSteps[status - 1].completed = true;
      }
      setSteps(newSteps);
    } else {
      // Do nothing
      console.log('No status match');
    }
  },
  [status]);

return (
<div className="container-fluid">
  <Timeline status={status} steps={steps} source={source} />
</div>
);
}

And here is my child component:

export default class Timeline extends React.Component {

  renderSteps() {
    const { steps } = this.props;

    return steps.map((step, index) => {
      console.log(step);
      console.log(steps);
      return (
        <div key={`test${index}`}>
          {step.title}
          {step.active && <span>is active</span>}
          {step.loading && <span>is loading</span>}
          {step.completed && <span>is completed</span>}
        </div>
      );
    });
  }

  render() {
    const { status, steps, source } = this.props;

    return (
        <div className="timeline">
          {this.renderSteps()}
        </div>
      </>
    );
  }
}

When i console.log steps props inside my child component, I see that they are correctly updated. (When status === 1, the first step active property is true )

But when i console.log step (inside my map function), none of the properties are updated. (When status === 1, the first step active property is false )

You can see on the capture below that something is not right (I already encountered this problem but unfortunately I can't remember how I solved it, and I am wondering if it's because of the useEffect hooks which I didn't use before this project.

在此处输入图像描述

Thank you for your help

Edit:Codesandbox here

Ok, I figured it out.

Since I got this code from another developer, I didn't understand everything that was implemented. I went to the React documentation to understand where the problem was coming from.

By passing a second parameter to the useEffect function, React can skip the effect and will not re-render the component for performance issues if there is not any change. As my status doesn't change (I change it manually for the moment), my component was not refreshing.

By adding [steps] width [status] inthe second parameter, everything works.

 useEffect(() => {
    if (status) {
      const newSteps = steps;
      newSteps[status - 1].active = true;
      if (status > 1) {
        newSteps[status - 2].completed = true;
      }
      if (status === 3) {
        newSteps[status - 1].active = false;
        newSteps[status - 1].completed = true;
      }
      setSteps(newSteps);
    } else {
      // Do nothing
      console.log('No status match');
    }
  }, [status, steps]);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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