React:为什么组件的构造函数只被调用一次?
React: Why component's constructor is called only once?
在 following example 中,单击 Item 2
时,将显示 Second 1
而不是 Second 2
。为什么?你会如何解决这个问题?
var guid = 0;
class Content extends React.Component {
constructor() {
guid += 1;
this.id = guid;
console.log('ctor', this.id); // called only once with 1
}
render() {
return (
<div className="content">
{this.props.title} - {this.id}
</div>
);
}
}
class MyApp extends React.Component {
constructor() {
this.items = ['Item 1', 'Item 2'];
this.state = {
activeItem: this.items[0]
};
}
onItemClick(item) {
this.setState({
activeItem: item
});
}
renderMenu() {
return (
<div className="menu">
<div onClick={this.onItemClick.bind(this, 'Item 1')}>Item 1</div>
<div onClick={this.onItemClick.bind(this, 'Item 2')}>Item 2</div>
</div>
);
}
renderContent() {
if (this.state.activeItem === 'Item 1') {
return (
<Content title="First" />
);
} else {
return (
<Content title="Second" />
);
}
}
render() {
return (
<div>
{this.renderMenu()}
{this.renderContent()}
</div>
);
}
}
React 的 reconciliation algorithm 假定在没有任何相反信息的情况下,如果自定义组件出现在后续渲染中的相同位置,则它与以前的组件相同,因此重用先前的实例而不是创建新的实例一.
如果您要实施 componentWillReceiveProps(nextProps)
,您会看到它被调用。
Different Node Types
It is very unlikely that a <Header>
element is going to generate a DOM that is going to look like what a <Content>
would generate. Instead of spending time trying to match those two structures, React just re-builds the tree from scratch.
As a corollary, if there is a <Header>
element at the same position in two consecutive renders, you would expect to see a very similar structure and it is worth exploring it.
Custom Components
We decided that the two custom components are the same. Since components are stateful, we cannot just use the new component and call it a day. React takes all the attributes from the new component and calls component[Will/Did]ReceiveProps()
on the previous one.
The previous component is now operational. Its render()
method is called and the diff algorithm restarts with the new result and the previous result.
如果你给每个组件 a unique key
prop,React 可以使用 key
变化来推断组件实际上已经被替换,并且会从头开始创建一个新组件,给它完整的组件生命周期.
renderContent() {
if (this.state.activeItem === 'Item 1') {
return (
<Content title="First" key="first" />
);
} else {
return (
<Content title="Second" key="second" />
);
}
}
在 following example 中,单击 Item 2
时,将显示 Second 1
而不是 Second 2
。为什么?你会如何解决这个问题?
var guid = 0;
class Content extends React.Component {
constructor() {
guid += 1;
this.id = guid;
console.log('ctor', this.id); // called only once with 1
}
render() {
return (
<div className="content">
{this.props.title} - {this.id}
</div>
);
}
}
class MyApp extends React.Component {
constructor() {
this.items = ['Item 1', 'Item 2'];
this.state = {
activeItem: this.items[0]
};
}
onItemClick(item) {
this.setState({
activeItem: item
});
}
renderMenu() {
return (
<div className="menu">
<div onClick={this.onItemClick.bind(this, 'Item 1')}>Item 1</div>
<div onClick={this.onItemClick.bind(this, 'Item 2')}>Item 2</div>
</div>
);
}
renderContent() {
if (this.state.activeItem === 'Item 1') {
return (
<Content title="First" />
);
} else {
return (
<Content title="Second" />
);
}
}
render() {
return (
<div>
{this.renderMenu()}
{this.renderContent()}
</div>
);
}
}
React 的 reconciliation algorithm 假定在没有任何相反信息的情况下,如果自定义组件出现在后续渲染中的相同位置,则它与以前的组件相同,因此重用先前的实例而不是创建新的实例一.
如果您要实施 componentWillReceiveProps(nextProps)
,您会看到它被调用。
Different Node Types
It is very unlikely that a
<Header>
element is going to generate a DOM that is going to look like what a<Content>
would generate. Instead of spending time trying to match those two structures, React just re-builds the tree from scratch.As a corollary, if there is a
<Header>
element at the same position in two consecutive renders, you would expect to see a very similar structure and it is worth exploring it.Custom Components
We decided that the two custom components are the same. Since components are stateful, we cannot just use the new component and call it a day. React takes all the attributes from the new component and calls
component[Will/Did]ReceiveProps()
on the previous one.The previous component is now operational. Its
render()
method is called and the diff algorithm restarts with the new result and the previous result.
如果你给每个组件 a unique key
prop,React 可以使用 key
变化来推断组件实际上已经被替换,并且会从头开始创建一个新组件,给它完整的组件生命周期.
renderContent() {
if (this.state.activeItem === 'Item 1') {
return (
<Content title="First" key="first" />
);
} else {
return (
<Content title="Second" key="second" />
);
}
}