【问题标题】:How do I make Component rerender when props passed from parent and state changed?当从父级传递的道具和状态发生变化时,如何使组件重新渲染?
【发布时间】:2019-12-14 15:13:24
【问题描述】:

我正在制作一个 Todolist。 Submit 组件处理来自用户的输入并向服务器发出 PUT 请求以更新数据库。 Progress 组件显示进度。当用户提交时,Submit 会向 Progress 发送 props,Progress 会调用 axios.get 来获取数据并更新状态。 props 成功传递,Progress 状态的变量确实发生了变化,但组件没有重新渲染。

提交.js

import Progress from './progress';

export default class Submit extends Component {
  constructor(props) {
    super(props);
    this.state = {
      updateProgress: 'No'
    }
  }

  handleSubmit = (e) => {
    // ...
    this.setState({updateProgress: 'Yes'}));
  }

  render() {
    return (
      <div>
      <div style={{visibility: 'hidden'}}>
        <Progress update={this.state.updateProgress} />
      </div>

      // Form
      </div>
    )
  }
}

progress.js

export default class Progress extends Component {
  constructor(props) {
    super(props);
    this.state = {
      tasksDone: 0
    };
  }  

  getData = () => {
    axios.get('/task')
    .then(res => {
      let resData = res.data[0];
      this.setState({tasksDone: resData.done});
    })
    .catch(err => console.log(err));
  }

  componentDidUpdate(prevProps) {
    if (this.props.update != prevProps.update) {
      console.log('Props changed');
      this.getData();
    }
  }

  componentDidMount() {
    this.getData();
  }

  render() {
    return (<div>You have done: {this.state.tasksDone}</div>)
  }
}

我知道 getData() 在第一次提交后不会再次被调用,因为传递的道具没有改变,但事实并非如此,因为它在第一次提交后就不起作用了。 当我在 componentDidUpdate() 中使用 console.log(this.state.tasksDone) 时,tasksDone 会更新,但不会重新渲染 div,即使我在调用 getData() 后尝试使用 forceUpdate()。 我读过其他问题,他们说变异状态不会触发重新渲染。我的 setState 只是变异了吗?我看到以这种方式改变状态是很常见的。我错过了什么?

重现问题:https://codesandbox.io/s/determined-curie-ipr6v

【问题讨论】:

标签: reactjs axios react-props react-state-management


【解决方案1】:

问题在于您对 Progress 的使用。 您正在更新的进度不是显示屏上显示的进度。

https://codesandbox.io/s/vigilant-ardinghelli-vd9nl 这是您提供的工作代码。

【讨论】:

  • 它似乎有效,但是“您正在更新的进度不是显示屏上显示的进度”是什么意思?
  • 在您的 index.js 中,您声明了要显示的进度。然后再次在您的 submit.js 中,您声明了另一个进度,但将其设置为隐藏。您正在更新的是 submit.js 中的隐藏进度。通过删除 index.js 中声明的 Progress 来修复它,并将 submit.js 中的可见性设置为 true
  • @BrianeuqsarraT 通过导入 Progress 两次,一个在 index 处,1 个在 submit 处,将创建 Progress 组件的两个实例,这就像从一个类中创建两个对象一样。然后对一个对象进行更改不会反映在另一个对象上。因此,您在一个实例中的更改不会反映在另一个实例中。
  • 是的,这是有道理的,但在我的源代码中,目的是显示与进度区域分开的提交表单区域(使用 Bootstrap 模式弹出窗口出现),所以我必须调用 在提交里面有一个传递道具的参考,但我不希望它出现在表单中,所以我使用样式来隐藏它并将它导入到 App 组件中以显示它。有什么办法可以实现吗?
  • 使用一些状态管理,比如react useContext,或者redux。它将允许您更新彼此无关的组件。
猜你喜欢
  • 1970-01-01
  • 2020-03-19
  • 2021-07-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-12
  • 2020-10-20
  • 2021-01-13
相关资源
最近更新 更多