道具React发生变化时如何渲染组件?

Posted

技术标签:

【中文标题】道具React发生变化时如何渲染组件?【英文标题】:How to render component when there is change in props 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 【参考方案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>

【讨论】:

以上是关于道具React发生变化时如何渲染组件?的主要内容,如果未能解决你的问题,请参考以下文章

React Native 克隆的子组件不会随着道具的变化而重新渲染

每次使用相同的给定道具 React Memo 渲染

如何防止我的功能组件使用 React 备忘录或 React 钩子重新渲染?

如何在 AngularJS 中实现组件组合(类似于 React 渲染道具模式)?

当父组件在 Next.js 应用程序中更新其道具时重新渲染 React 子组件

React:如何动画化渲染组件的变化?