【发布时间】:2018-09-16 00:59:46
【问题描述】:
我编写了一个简单的 React POC,其中有一个主组件和两个子组件。应用程序的整个状态都保存在 Main 组件中。当状态发生变化时,当新状态作为 props 传递时,子组件会重新渲染。
import * as React from 'react'
import * as ReactDOM from 'react-dom'
class Comp1 extends React.Component<IProps1, any> {
render() {
console.log('going to render Component1')
return (
<React.Fragment>
<input type='text' value={this.props.curtext} onChange={(e) => this.props.handleChange(e.target.value)} />
<button onClick={(e) => this.props.onSave(this.props.curtext)}>save</button>
</React.Fragment>
)
}
}
class Comp2 extends React.Component<IProps2, any> {
render() {
console.log('going to render Component2')
return (
<React.Fragment>
<ul>
{this.props.items.map((item, index) => <li key={index}>{item}</li>)}
</ul>
</React.Fragment>
)
}
}
class Main extends React.Component<any, IState> {
constructor(props: any) {
super(props)
this.state = {
currtext: "",
items: []
}
this.handleChange = this.handleChange.bind(this)
this.onSave = this.onSave.bind(this)
}
handleChange(text: string) {
this.setState({currtext: text})
}
onSave(text: string) {
var copy = this.state.items;
copy.push(text)
this.setState({currtext: "", items: copy})
}
render() {
return (
<React.Fragment>
<Comp1 handleChange={this.handleChange} curtext={this.state.currtext} onSave={this.onSave} />
<Comp2 items= {this.state.items} />
</React.Fragment>
)
}
}
ReactDOM.render(<Main />, document.getElementById("root"))
interface IState {
currtext: string
items: Array<string>
}
interface IProps1 {
handleChange: (text: string) => void,
curtext: string,
onSave: (text: string) => void
}
interface IProps2 {
items: Array<string>
}
该应用唯一的问题是,当状态的“currtext”属性发生变化时,Component2仍然会重新渲染。
我所期望的是 curtext 发生变化,然后 Component1 被渲染,当项目发生变化时,Component2 重新渲染。
但现在我看到 Component2 在输入文本框中的每次击键时都会重新渲染,这只会改变 Component2 不关心的状态部分。
编辑:: 根据下面的建议,我将组件 2 的代码更改为
class Comp2 extends React.Component<IProps2, any> {
shouldComponentUpdate(nextProps: IProps2, nextState: any) {
console.log(nextProps.items);
console.log(this.props.items);
if (nextProps.items.toString() === this.props.items.toString()) {
return false
} else {
return true
}
}
render() {
console.log('going to render Component2')
return (
<React.Fragment>
<ul>
{this.props.items.map((item, index) => <li key={index}>{item}</li>)}
</ul>
</React.Fragment>
)
}
}
现在,如果我在文本框中输入内容并单击保存。我看到 nextProps.items 和 this.props.items 总是相同的,因此我的 component2 根本不渲染。
【问题讨论】:
标签: reactjs typescript