这篇文章给大家介绍的内容是关于React中跨组件分发状态的三种方法介绍,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。
当我问自己第一百次时,我正在研究一个典型的CRUD屏幕:“我应该将状态保留在这个组件中还是将其移动到父组件?”。
如果需要对子组件的状态进行轻微控制。您可能也遇到了同样的问题。
让我们通过一个简单的例子和三种修复方法来回顾它。前两种方法是常见的做法,第三种方法不太常规。
为了向您展示我的意思,我将使用一个简单的书籍CRUD(译者注:增加(Create)、读取查询(Retrieve)、更新(Update)和删除(Delete))屏幕(如此简单,它没有创建和删除操作)。
我们有三个组成部分。
那么,我们的状态是什么?好吧,
import React, { Component } from "react"; import { render } from "react-dom"; const books = [ { title: "The End of Eternity", author: "Isaac Asimov" }, //... ]; const BookList = ({ books, onEdit }) => (
Book Title | Actions |
---|---|
{book.title} |
在codesandbox尝试一下
看起来不错,但是他不起作用。
我们正在创建组件实例时初始化
我们改如何修复它?
一种常见的方法是将状态提升,将
//... class BookForm extends Component { render() { if (!this.props.book) return null; return ( <form> <h3>Book</h3> <label> Title: <input value={this.props.book.title} onChange={e => this.props.onChange({ ...this.props.book, title: e.target.value })} /> </label> <label> Author: <input value={this.props.book.author} onChange={e => this.props.onChange({ ...this.props.book, author: e.target.value })} /> </label> <button onClick={() => this.props.onSave()}>Save</button> </form> ); } } class BookApp extends Component { state = { books: books, activeBook: null, activeIndex: -1 }; render() { const { books, activeBook, activeIndex } = this.state; return ( <div> <BookList books={books} onEdit={index => this.setState({ activeBook: { ...books[index] }, activeIndex: index })} /> <BookForm book={activeBook} onChange={book => this.setState({ activeBook: book })} onSave={() => this.setState({ books: Object.assign([...books], { [activeIndex]: activeBook }), activeBook: null, activeIndex: -1 })} /> </div> ); } } //...
现在它可以工作,但对我来说,提升
在codesandbox尝试一下
现在它可以工作,但对我来说,提升
//... 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 ( <form> <h3>Book</h3> <label> Title: <input value={this.state.title} onChange={e => this.setState({ title: e.target.value })} /> </label> <label> Author: <input value={this.state.author} onChange={e => this.setState({ author: e.target.value })} /> </label> <button onClick={() => this.props.onSave({ ...this.state })}> Save </button> </form> ); } } //...
在codesandbox尝试一下
这种方法通常被认为是一种不好的做法,因为它违背了React关于拥有单一事实来源的想法。我不确定是这种情况,然而,同步状态并不总是那么容易。此外,我尽量避免使用生命周期方法。
但为什么我们要回收旧的状态呢?每次用户选择一本书时,拥有一个全新状态的新实例是不是有意义?
为此,我们需要告诉React停止使用旧实例并创建一个新实例。这就是key prop的用途。
//... class BookApp extends Component { state = { books: books, activeIndex: -1 }; render() { const { books, activeIndex } = this.state; const activeBook = books[activeIndex]; return ( <div> <BookList books={books} onEdit={index => this.setState({ activeIndex: index })} /> <BookForm key={activeIndex} book={activeBook} onSave={book => this.setState({ books: Object.assign([...books], { [activeIndex]: book }), activeIndex: -1 })} /> </div> ); } } //...
在codesandbox尝试一下。
如果元素具有与上一个渲染不同的键,则React会为其创建一个新实例。因此,当用户选择新书时,
相关文章推荐:
React-JSX中如何实现Class与Style的动态绑定(附实例)
The above is the detailed content of An introduction to three methods for distributing state across components in React. For more information, please follow other related articles on the PHP Chinese website!