// Child component
class Button extends React.Component {
render() {
console.log("Render of Button called");
return (
<button onClick={this.props.handleClick}>
{this.props.children}
</button>
);
}
}
// Parent component
class ButtonRenderer extends React.Component {
state = {
count: 0
};
increment() {
this.setState({
count: this.state.count + 1
});
}
render() {
console.log("Render of ButtonRenderer called.");
return (
<div>
<Button handleClick={this.increment.bind(this)}>Click me</Button>
<div>Count: {this.state.count}</div>
</div>
);
}
}
function init() {
var rootElement = document.getElementById("root");
const childElement = <ButtonRenderer />;
ReactDOM.render(childElement, rootElement);
}
每次单击该按钮,父组件中的状态都会更改,因此将随子组件Button.render一起调用ButtonRenderer.render。为什么?
我尝试了所有3种调用事件处理程序的方法:
使用内联绑定()的
...
increment = () => {
this.setState({
count: ++this.state.count
});
}
...
<Button handleClick={this.increment}>Click me</Button>
...
...
increment(){
this.setState({
count: ++this.state.count
});
}
...
<Button handleClick={() => {this.increment();}}>Click me</Button>
...
对于每一次单击,所有3种方法都会执行这两个
方法。
我希望approach1和approach2不会在每次单击时都调用Button的render方法,因为没有任何变化。我希望approach3在每次点击时都会调用Button的render方法,因为我使用的是内联箭头函数,它将为每个render for ButtonRendered类创建一个新函数。
每次单击按钮时的浏览器控制台输出:
Render of ButtonRenderer called.
Render of Button called
我的问题是:当没有专业人员更改为Button comp时,为什么approach1 (使用bind)和approach2(使用类属性)都在调用子组件Button的render()方法?
发布于 2019-06-13 06:34:39
如果要避免不需要的渲染,请使用PureComponent
:
// Child component
class Button extends React.PureComponent {
render() {
console.log("Render of Button called");
return (
<button onClick={this.props.handleClick}>
{this.props.children}
</button>
);
}
}
// Parent component
class ButtonRenderer extends React.Component {
state = {
count: 0
};
increment = () => {
this.setState({
count: this.state.count + 1
});
}
render() {
console.log("Render of ButtonRenderer called.");
return (
<div>
<Button handleClick={this.increment}>Click me</Button>
<div>Count: {this.state.count}</div>
</div>
);
}
}
function init() {
var rootElement = document.getElementById("root");
const childElement = <ButtonRenderer />;
ReactDOM.render(childElement, rootElement);
}
init();
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
发布于 2019-06-13 06:33:57
如果父组件被更新,React是否总是更新该组件中的所有直接子组件?
不是的。仅当shouldComponentUpdate()返回true时,React才会重新呈现组件。默认情况下,该方法总是返回true,以避免新手出现任何细微的bug(正如William B所指出的,DOM实际上不会更新,除非发生了更改,从而降低了影响)。Font
实际上,默认情况下,子组件将始终重新呈现,除非您显式地告诉then不这样做。应该在这里实现shouldComponentUpdate
,以防止不必要的渲染,除非属性值发生变化。或者使用PureComponent
发布于 2019-06-13 06:43:59
解决方案# 1。
// Parent component
class ButtonRenderer extends React.Component {
state = {
count: 0
};
increment = () => {
this.setState({
count: ++this.state.count
});
}
render() {
console.log("Render of ButtonRenderer called.");
return (
<div>
<Button handleClick={this.increment}>Click me</Button>
<div>Count: {this.state.count}</div>
</div>
);
}
}
您可以通过在shouldComponentUpdate
方法中返回false来避免更新。您还可以在其中编写业务登录,并根据它返回false
或true
。
// Child component
class Button extends React.PureComponent {
constructor (props) {
super(props)
}
render() {
console.log("Render of Button called");
return (
<button onClick={this.props.handleClick}>
{this.props.children}
</button>
);
}
}
// Parent component
class ButtonRenderer extends React.Component {
state = {
count: 0
};
increment = () => {
this.setState({
count: ++this.state.count
});
}
render() {
console.log("Render of ButtonRenderer called.");
return (
<div>
<Button handleClick={this.increment}>Click me</Button>
<div>Count: {this.state.count}</div>
</div>
);
}
}
当你扩展到React.PureComponent
而不是React.Component
时,一些生命周期方法。在这种情况下,这是可行的。
如果你对我的回答有帮助,请考虑投赞成票。
https://stackoverflow.com/questions/56571069
复制相似问题