【问题标题】:How to render component when there is change in props React?道具React发生变化时如何渲染组件?
【发布时间】:2020-10-20 13:23:05
【问题描述】:

如果 props 有变化,我想渲染组件。

当有setState 但我不能在render()setState 时渲染组件,它将处于无限循环中。

我尝试使用getDerivedStateFromProps,但由于它是静态的,我无法在其中使用 forceUpdate()。

我的问题是如何检测道具的变化,一旦检测到变化,如何启动渲染功能。

【问题讨论】:

  • 这能回答你的问题吗? Re-render React component when prop changes
  • 您可以在构造函数中的state 中设置prop,同时您可以使用getDerivedStateFromProp 来更新相同的值,以检查现有状态和新道具的值。这样,当 prop 更新时,组件将被重新渲染
  • 默认情况下,子组件将在每次道具更改时重新渲染。你确定不使用memoPureComponent

标签: javascript reactjs


【解决方案1】:

我认为 Damian 指出的副本显示了如何做到这一点,但我在这里添加了一个同步示例,其中最初基于 props 设置状态是在构造函数而不是 componentDidMount 中完成的。

稍后在 componentDidUpdate 中检测到对 props 的更改,并将使用已排序的数据再次设置状态。

class List extends React.PureComponent {
  sortData() {
    //only sort the data, not set the state. Shallow copy
    //  props.data because Array.prototype.sort will mutate
    //  props.data if you don't it won't cause a re render
    //  because you'll be setting state with a mutated array
    return [...this.props.data].sort(
      (a, b) => a.localeCompare(b) * this.props.direction
    );
  }
  constructor(props) {
    super(props);
    //initially set the state with the sored data
    this.state = { data: this.sortData() };
  }

  componentDidUpdate({ direction, data }) {
    //if props.data or props.direction changed
    //  set the state again with sorted data
    if (
      this.props.direction !== direction ||
      this.props.data !== data
    ) {
      this.setState({ data: this.sortData() });
    }
  }
  render() {
    return (
      <ul>
        {/* not using props.data but sorted state.data */}
        {this.state.data.map((item) => (
          <li key={item}>{item}</li>
        ))}
      </ul>
    );
  }
}
const data = ['a', 'b', 'c', 'd'];
function App() {
  const [direction, setDirection] = React.useState(1);
  return (
    <div>
      <div>
        <button
          onClick={() =>
            setDirection((d) => (d === 1 ? -1 : 1))
          }
        >
          toggle sort direction
        </button>
      </div>
      <List data={data} direction={direction} />
    </div>
  );
}

ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>


<div id="root"></div>

【讨论】:

    猜你喜欢
    • 2019-12-10
    • 1970-01-01
    • 1970-01-01
    • 2021-06-21
    • 2021-01-13
    • 2023-02-02
    • 2019-04-10
    • 1970-01-01
    • 2021-07-13
    相关资源
    最近更新 更多