为啥这个子组件不重新渲染?
Posted
技术标签:
【中文标题】为啥这个子组件不重新渲染?【英文标题】:Why doesn't this child component rerender?为什么这个子组件不重新渲染? 【发布时间】:2017-07-12 15:25:55 【问题描述】:我正在尝试使用 ReactJS,并试图了解如何触发子组件渲染。在 ReactJS 中,如果我设置这样的示例:
var externalCounterVar = 10
class Counter extends React.Component
constructor(props)
super(props);
this.state = props;
render()
console.log('rendering counter')
return (
<div> externalCounterVar </div>
)
class Main extends React.Component
constructor(props)
super(props);
handleClick()
externalCounterVar += 1;
rerender()
this.render();
render()
console.log('rendering');
return (
<div>
<button onClick=this.rerender.bind(this) />
<Counter counter=externalCounterVar />
</div>
)
ReactDOM.render(<Main />, document.getElementById('root'));
我不确定我是否理解为什么当您“重新渲染”时它调用 Main 的渲染方法而不是 Counter?似乎它应该调用这两个渲染方法,因为它正在渲染 Main 并且 Counter 是 Main 的子级。
所以当调用 rerender 时,'rendering' 会打印,但 'rendering counter' 不会。
【问题讨论】:
【参考方案1】:在这种情况下,您不必使用rerender
方法,也可以使用setState
方法重新渲染您需要更新状态的所有子组件。并且根据this,您必须“向上移动状态”。
这是我的例子:
class Counter extends React.Component
render()
console.log('rendering counter');
return (<div> this.props.counter </div>);
class Main extends React.Component
constructor(props)
super(props);
this.state = counter: props.counter;
this.handleClick = this.handleClick.bind(this);
handleClick()
this.setState(prevState => (counter: ++prevState.counter));
render()
console.log('rendering');
return (
<div>
<button onClick=this.handleClick />
<Counter counter=this.state.counter />
</div>
);
var externalCounterVar = 10;
ReactDOM.render(
<Main counter=externalCounterVar />,
document.getElementById('root')
);
【讨论】:
【参考方案2】:在某些情况下,您可以使用this.forceUpdate()
调用重新渲染。
但是,如果你不能做到这一点,就不要这样做。
https://facebook.github.io/react/docs/react-component.html#forceupdate
【讨论】:
【参考方案3】:您似乎忽略了使用 React 的主要好处之一,即状态的工作原理。
-
您永远不需要在 React 组件中调用
this.render
你不应该动态设置状态,即:this.state = ...
您应该始终使用this.setState
来设置您的状态。
重写后,您的代码应如下所示:
const externalCounterVar = 10
class Counter extends React.Component
render()
console.log('rendering counter')
return (
<div> this.props.counter </div>
)
class Main extends React.Component
state =
counter: externalCounterVar
handleClick()
this.setState(counter: this.state.counter + 1);
render()
console.log('rendering');
return (
<div>
<button onClick=this.handleClick.bind(this) />
<Counter counter=this.state.counter />
</div>
)
通过调用this.setState
,React 自动知道它需要重新渲染你的组件,因此所有子组件也将被重新渲染。
希望这会有所帮助!
【讨论】:
我只是在搞乱 api,知道这是一个反模式。以上是关于为啥这个子组件不重新渲染?的主要内容,如果未能解决你的问题,请参考以下文章
为啥组件在状态更改后不重新渲染。在 react-native 函数组件中