简体   繁体   English

反应:道具未在 map function 内部更新

[英]React : Prop not updated inside of a map function

Edit:Codesandbox here编辑:这里的 Codesandbox

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.当我在子组件中执行 console.log steps道具时,我看到它们已正确更新。 (When status === 1, the first step active property is true ) (当status === 1时,第一步active属性为true

But when i console.log step (inside my map function), none of the properties are updated.但是当我执行 console.log step (在我的 map 函数中)时,没有更新任何属性。 (When status === 1, the first step active property is false ) (当status === 1时,第一步active属性为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.您可以在下面的捕获中看到有些地方不对(我已经遇到过这个问题,但不幸的是我不记得我是如何解决它的,我想知道这是否是因为我在这个项目之前没有使用的useEffect挂钩.

在此处输入图像描述

Thank you for your help谢谢您的帮助

Edit:Codesandbox here编辑:这里的 Codesandbox

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.我查看了 React 文档以了解问题出在哪里。

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.通过将第二个参数传递给useEffect function, React 可以跳过效果,并且如果没有任何更改,则不会因性能问题重新渲染组件。 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.通过在第二个参数中添加[steps] width [status] ,一切正常。

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

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

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