React 动态渲染组件(对象分配与函数 return)
React dynamically rendering component (object assign vs. function return)
我在这里碰壁了,这意味着我不能完全弄清楚为什么接下来的两个版本的代码表现如此不同。
在第一个版本中,当我初始化 this.childComponent = (<ChildComp />)
时,当我更改 Parent
的状态(通过 setState()
)时,它的属性似乎没有更新。即使实际调用了 setState()
,并且更新了 Parent
的状态,也会发生这种情况。
在第二个版本中,当我实际初始化一个 returns 组件 (this.childComponent = () => {return (<ChildComp />)}
) 的函数时,一切都像魅力一样工作,道具被更新。
我正在使用第二个版本(因为它有效),但我想了解为什么这个有效而第一个无效。
这是子组件:
class Child extends React.Component {
render() {
return (
<button onClick=(this.props.setValue())>
{this.props.value}
</button>
)
}
}
我有下两个版本的父组件:
1.
class Parent extends React.Component {
constructor() {
this.state = {
value: 1
}
this.childComponent = (
<Child value={this.state.value}
setValue={() => this.setValue()}/>
)
}
setValue() {
this.setState({value: 2})
}
render () {
return ( {this.childComponent} )
}
}
2.(this.childComponent
现在是 returns 反应元素的函数)
class Parent extends React.Component {
constructor() {
this.state = {
value: 1
}
this.childComponent = () => {
return (
<Child value={this.state.value}
setValue={() => this.setValue()}/>
)
}
}
setValue() {
this.setState({value: 2})
}
render () {
return ( {this.childComponent()} )
}
}
我已尝试简化代码,以便更容易理解我的问题。
提前致谢
在
之后的第一种情况下,您没有 return
this.childComponent = (
<Child value={this.state.value}
setValue={() => this.setValue()}/>
)
在构造函数中定义,只执行一次,现在是静态值。
而它会起作用,因为它是一个每次调用时都会执行的函数。
如果您想使用第一种方法,请在渲染中定义子组件而不是构造函数,因为在每次更改时都会调用渲染。您的代码也有很多错误。请参阅下面的工作片段
class Parent extends React.Component {
constructor() {
super();
this.state = {
value: 1
}
}
setValue() {
this.setState({value: 2})
}
render () {
const childComponent = (
<Child value={this.state.value}
setValue={() => this.setValue()}/>
)
return ( <div>{childComponent}</div> )
}
}
class Child extends React.Component {
render() {
return (
<button onClick={this.props.setValue}>
{this.props.value}
</button>
)
}
}
ReactDOM.render(<Parent/>, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>
React 使用一种名为 reconciliation 的策略来有效地更新 DOM 每当其内部状态发生变化时。通常,这发生在 setState
调用之后。
在您的第一个示例中,Parent
组件中的 render
方法始终 returns 相同的 Child
组件,因为它仅在 [=14] 中创建一次=].因此,协调算法找不到任何更改,因为没有任何更改。
我想指出 <Child value={this.state.value} setValue={() => this.setValue()}/>
只是 React.createElement(Child, {value: this.state.value, setValue: () => this.setValue()}, null)
的语法糖。 createElement 只是 returns 一个对象。
在您的第二个示例中,每次 render
调用时,您都在调用 childComponent
,后者又会创建一个新的 Child
组件。
我在这里碰壁了,这意味着我不能完全弄清楚为什么接下来的两个版本的代码表现如此不同。
在第一个版本中,当我初始化 this.childComponent = (<ChildComp />)
时,当我更改 Parent
的状态(通过 setState()
)时,它的属性似乎没有更新。即使实际调用了 setState()
,并且更新了 Parent
的状态,也会发生这种情况。
在第二个版本中,当我实际初始化一个 returns 组件 (this.childComponent = () => {return (<ChildComp />)}
) 的函数时,一切都像魅力一样工作,道具被更新。
我正在使用第二个版本(因为它有效),但我想了解为什么这个有效而第一个无效。
这是子组件:
class Child extends React.Component {
render() {
return (
<button onClick=(this.props.setValue())>
{this.props.value}
</button>
)
}
}
我有下两个版本的父组件:
1.
class Parent extends React.Component {
constructor() {
this.state = {
value: 1
}
this.childComponent = (
<Child value={this.state.value}
setValue={() => this.setValue()}/>
)
}
setValue() {
this.setState({value: 2})
}
render () {
return ( {this.childComponent} )
}
}
2.(this.childComponent
现在是 returns 反应元素的函数)
class Parent extends React.Component {
constructor() {
this.state = {
value: 1
}
this.childComponent = () => {
return (
<Child value={this.state.value}
setValue={() => this.setValue()}/>
)
}
}
setValue() {
this.setState({value: 2})
}
render () {
return ( {this.childComponent()} )
}
}
我已尝试简化代码,以便更容易理解我的问题。
提前致谢
在
之后的第一种情况下,您没有 returnthis.childComponent = (
<Child value={this.state.value}
setValue={() => this.setValue()}/>
)
在构造函数中定义,只执行一次,现在是静态值。
而它会起作用,因为它是一个每次调用时都会执行的函数。
如果您想使用第一种方法,请在渲染中定义子组件而不是构造函数,因为在每次更改时都会调用渲染。您的代码也有很多错误。请参阅下面的工作片段
class Parent extends React.Component {
constructor() {
super();
this.state = {
value: 1
}
}
setValue() {
this.setState({value: 2})
}
render () {
const childComponent = (
<Child value={this.state.value}
setValue={() => this.setValue()}/>
)
return ( <div>{childComponent}</div> )
}
}
class Child extends React.Component {
render() {
return (
<button onClick={this.props.setValue}>
{this.props.value}
</button>
)
}
}
ReactDOM.render(<Parent/>, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>
React 使用一种名为 reconciliation 的策略来有效地更新 DOM 每当其内部状态发生变化时。通常,这发生在 setState
调用之后。
在您的第一个示例中,Parent
组件中的 render
方法始终 returns 相同的 Child
组件,因为它仅在 [=14] 中创建一次=].因此,协调算法找不到任何更改,因为没有任何更改。
我想指出 <Child value={this.state.value} setValue={() => this.setValue()}/>
只是 React.createElement(Child, {value: this.state.value, setValue: () => this.setValue()}, null)
的语法糖。 createElement 只是 returns 一个对象。
在您的第二个示例中,每次 render
调用时,您都在调用 childComponent
,后者又会创建一个新的 Child
组件。