当前位置: 首页 > Web前端 > CSS

在React中跨组件分布状态的三种方式

时间:2023-03-31 12:30:38 CSS

在React中跨组件分布状态的三种方式父组件?”。如果您需要轻微控制子组件的状态。您可能遇到过同样的问题。让我们用一个简单的例子和??三个修复来回顾它。前两种方法很常见,第三种方法不太常见。问题;为了向您展示我的意思,我将使用一个简单的书本CRUD(译者注:创建、检索、更新和删除)屏幕(如此简单,它没有创建和删除操作)。我们有三个组成部分。是一个显示书籍列表和编辑它们的按钮的组件。有两个输入和一个按钮来保存对书的更改。和包含其他两个组件的。那么,我们的状态是什么?那么,应该跟踪书籍列表并标识当前正在编辑的书籍的内容。没有任何状态。应该保持输入的当前状态,直到单击“保存”按钮。importReact,{Component}from"react";import{render}from"react-dom";constbooks=[{title:"TheEndofEternity",author:"IsaacAsimov"},//...];constBookList=({books,onEdit})=>(

{books.map((book,index)=>())}
BookTitleActions
{book.title}onEdit(index)}>编辑
);classBookFormextendsComponent{state={...this.props.book};render(){if(!this.props.book)返回null;return(

Book

this.props.onSave({...this.state})}>保存);}}classBookAppextendsComponent{state={books:books,activeIndex:-1};render(){const{books,activeIndex}=this.state;constactiveBook=books[activeIndex];return(
this.setState({activeIndex:index})}/>this.setState({书籍:Object.assign([...books],{[activeIndex]:book}),activeIndex:-1})}/>
);}}render(,document.getElementById("root"));在codesandbox中试一下看起来不错,但是他不行我们在创建组件实例的时候初始化了状态,所以当从列表中选择了另一本书时,parent是没办法知道的需要改变它。我们如何解决它?方法1:受控组件一种常见的方法是提升状态,将变成受控组件。我们删除状态,将activeBook添加到状态,并向添加一个onChange属性,我们在每个输入上调用它。//...classBookFormextendsComponent{render(){if(!this.props.book)returnnull;返回(

Book

this.props.onSave()}>保存);}}类BookApp扩展Component{state={books:books,activeBook:null,activeIndex:-1};render(){const{books,activeBook,activeIndex}=this.state;return(
this.setState({activeBook:{...books[index]},activeIndex:index})}/>this.setState({activeBook:book})}onSave={()=>this.setState({books:Object.assign([...books],{[activeIndex]:activeBook}),activeBook:null,activeIndex:-1})}/>
);}}//...方法2:同步状态现在它起作用了,但我觉得在用户单击后提升的状态是错误的“不关心书籍的任何更改,直到保存”,那么为什么它需要保持它自己的状态呢?在codesandbox中尝试它,现在它可以工作了,但是提升的状态对我来说感觉不对。在用户点击保存之前不关心书的任何变化,那么为什么它需要保持它自己的状态呢?//...classBookFormextendsComponent{state={...this.props.book};componentWillReceiveProps(nextProps){constnextBook=nextProps.book;if(this.props.book!==nextBook){这个。setState({...下一本书});}}render(){if(!this.props.book)返回null;return(

Book

<按钮onClick={()=>这个.props.onSave({...this.state})}>保存);}}//...在codesandbox中尝试这通常被认为是一种不好的做法,因为它违背了React拥有单一真实来源的想法我不确定情况是否如此,但是,同步并不总是那么容易状态。另外,我尽量避免使用生命周期方法。方法3:由Key控制的组件但是为什么我们要回收旧状态?每次用户选择一本书时都有一个全新状态的新实例不是很有意义吗?为此,我们需要告诉React停止使用旧实例并创建一个新实例。这就是关键道具的用途。//...classBookAppextendsComponent{state={books:books,activeIndex:-1};render(){const{books,activeIndex}=this.state;constactiveBook=books[activeIndex];return(
this.setState({activeIndex:index})}/>this.setState({books:Object.assign([...books],{[activeIndex]:book}),activeIndex:-1})}/>
);}}//...试试吧在codesandbox上。如果该元素与之前的渲染有不同的键,React会创建一个新的实例。因此,当用户选择一本新书时,的键发生变化,创建一个新的组件实例,并从props初始化状态。有什么收获?重用组件实例意味着更少的DOM突变,这意味着更好的性能。因此,当我们强制React创建一个组件的新实例时,我们会因为额外的DOM突变而获得一些开销。但是对于像这样的键变化不太快且组件不大的情况,这种开销是最小的。谢谢阅读。