详解在React中跨组件分发状态的三种方法(2)

现在它可以工作,但对我来说,提升 <BookForm /> 的状态感觉不对。在用户单击“保存”之前, <BookApp /> 不关心对书的任何更改,那么为什么需要将其保持在自己的状态?

方法2:同步state

现在它可以工作,但对我来说,提升<BookForm />的状态感觉不对。在用户单击“保存”之前,<BookApp />不关心对书的任何更改,那么为什么需要将其保持在自己的状态?

//... class BookForm extends Component { state = { ...this.props.book }; componentWillReceiveProps(nextProps) { const nextBook = nextProps.book; if (this.props.book !== nextBook) { this.setState({ ...nextBook }); } } render() { if (!this.props.book) return null; return ( &lt;form&gt; <h3>Book</h3> &lt;label&gt; Title: &lt;input value={this.state.title} onChange={e =&gt; this.setState({ title: e.target.value })} /&gt; &lt;/label&gt; &lt;label&gt; Author: &lt;input value={this.state.author} onChange={e =&gt; this.setState({ author: e.target.value })} /&gt; &lt;/label&gt; &lt;button onClick={() =&gt; this.props.onSave({ ...this.state })}&gt; Save &lt;/button&gt; &lt;/form&gt; ); } } //...

这种方法通常被认为是一种不好的做法,因为它违背了React关于拥有单一事实来源的想法。我不确定是这种情况,然而,同步状态并不总是那么容易。此外,我尽量避免使用生命周期方法。

方法3:由Key控制的组件

但为什么我们要回收旧的状态呢?每次用户选择一本书时,拥有一个全新状态的新实例是不是有意义?

为此,我们需要告诉React停止使用旧实例并创建一个新实例。这就是key prop的用途。

//... class BookApp extends Component { state = { books: books, activeIndex: -1 }; render() { const { books, activeIndex } = this.state; const activeBook = books[activeIndex]; return ( <div> &lt;BookList books={books} onEdit={index =&gt; this.setState({ activeIndex: index })} /&gt; &lt;BookForm key={activeIndex} book={activeBook} onSave={book =&gt; this.setState({ books: Object.assign([...books], { [activeIndex]: book }), activeIndex: -1 })} /&gt; </div> ); } } //...

如果元素具有与上一个渲染不同的键,则React会为其创建一个新实例。因此,当用户选择新书时,<BookForm />的键更改,将创建组件的新实例,并从props初始化状态。

有什么收获?重用组件实例意味着更少的DOM突变,这意味着更好的性能。因此,当我们强制React创建组件的新实例时,我们会为额外的DOM突变获得一些开销。但是对于这样的情况,这种开销是最小的,其中密钥没有变化太快而且组件不大。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/e0b36ee5777d4c4354f0f573fcb8a0f4.html