React - 狀態提升

從入門的角度來聊一下React 的狀態提升。

我們先來看一下React官網是怎么介紹這一概念的:

使用 react 經常會遇到幾個組件需要共用狀態數據的情況。這種情況下,我們最好將這部分共享的狀態提升至他們最近的父組件當中進行管理。

很簡單的一句介紹,由此我們可以很清楚的明白React狀態提升主要就是用來處理父組件和子組件的數據傳遞的;他可以讓我們的數據流動的形式是自頂向下單向流動的,所有組件的數據都是來自于他們的父輩組件,也都是由父輩組件來統一存儲和修改,再傳入子組件當中。

舉個栗子

現在我們需要實現一個統計總價的功能:

1、首先,先寫一個父組件:

class Category extends React.Component { constructor(props){super(props);this.state = {name: "React.JS"}}render(){return <h1>{this.state.name}</h1>}
}
ReactDOM.render(<Category />,document.getElementById('app')
)復制代碼
2、再定義一個子組件,并拿到父組件傳遞下來的props值:

// 子組件
class Children extends React.Component {constructor(props){super(props);}render(){return(<div><label>{this.props.num}<input value={this.props.num} /><button>+</button></label></div>)}
}
// 父組件
class Category extends React.Component {constructor(props){super(props);this.state = {name: "React.JS",num1: 0}}render(){return(<div><h2>{this.state.num1}</h2><Children num={this.state.num1} /></div>)}
}復制代碼

? ? ? 現在我們可以看到,Children這個子組件的數據是從父組件傳下來,通過this.props拿到? ? ? ? ? 的,但是現在還不能在子組件上面去修改父組件的數據,所以我們的子組件的數據也無? ? ? ? ? ? 法得到改變。

3、現在我們在子組件里面定義屬性,來觸發父組件的事件:

class Children extends React.Component {constructor(props){super(props);}// input輸入框事件setNum(e){this.props.setNum(e.target.value)}// 按鈕遞增事件addNum(){this.props.addNum()}render(){return(<div><label>{this.props.num}<input onChange={(e)=>this.setNum(e)} value={this.props.num} /><button onClick={()=>this.addNum()}>+</button></label></div>)}
}
class Category extends React.Component {constructor(props){super(props);this.state = {name: "React.JS",// 將子組件的需要用到的數據存放在父組件內,在子組件內通過this.props可以取到num1: 0}}// 處理子組件傳上來觸發input輸入框的處理事件setNum(e){this.setState({num1: parseInt(e)})}// 處理子組件傳上來觸發button按鈕的處理事件addNum(){this.setState({num1: this.state.num1 += 1})}render(){return(<div><h2>{this.state.num1}</h2>// 子組件通過this.props可以觸發對應綁定的事件來修改自身的數據<Children addNum={()=>this.addNum()} setNum={(e)=>this.setNum(e)} num={this.state.num1} /></div>)}
}復制代碼

到這一步,功能已經實現了,子組件通過this.props去拿父組件的數據,并可以觸發屬性上面綁定的對應函數來修改父組件的數據,使子組件的數據得到更新;

其實可以看出,Children這個組件的數據不是獨立的,而是來自Category組件傳下來的,所以,這個Children組件是可以隨意復用的,只需要在他的父組件Category上為他存放一個給她傳遞數據的變量就OK了。

1、首先,我們在Category類的構造函數里的this.state內添加一個新的變量來處理我們即將新? ? ? ?增的另一個子組件:

constructor(props){super(props);this.state = {name: "React.JS",num1: 0,// 添加一個用來處理新組件數據的變量num2: 0    <==================================================}
}復制代碼

2、然后在Category組件里我們再寫一個新的Children組件,屬性上面綁定的數據全部換成們? ? ? ? ?剛才定義的新變量:

render(){return(<div><h2>{this.state.num1}</h2><Children addNum={()=>this.addNum()} setNum={(e)=>this.setNum(e)} num={this.state.num1} /><Children num={this.state.num2} /></div>)
}復制代碼

3、給他綁定屬性事件來修改處理他的變量:

class Category extends React.Component {constructor(props){super(props);this.state = {name: "React.JS",num1: 0,num2: 0}}
// 處理num1數據的子組件setNum(e){this.setState({num1: parseInt(e)})}addNum(){this.setState({num1: this.state.num1 += 1})}
// 處理num2數據的子組件newSetNum(e){this.setState({num2: parseInt(e)})}newAddNum(){this.setState({num2: this.state.num2 += 1})}render(){return(<div>// 這里接收兩個組件的數據總和<h2>{this.state.num1 + this.state.num2}</h2><Children addNum={()=>this.addNum()} setNum={(e)=>this.setNum(e)} num={this.state.num1} />// 在屬性上面綁定新的事件來處理該組件的事件<Children addNum={()=>this.newAddNum()} setNum={(e)=>this.newSetNum(e)} num={this.state.num2} /></div>)}
}復制代碼

現在,看一下實際效果:


*總結:

所以,React的狀態提升,其實是為了組件之間的數據更加單向性,在數據的傳輸上始終只會出現一對一的情況,在處理上,也方便我們只需要在向子組件傳遞數據的那個父輩組件上進行操作,并傳回子組件,使得數據更新,這種方法也體現了React的單向數據流的設計思想,在復用組件的時候,組件的數據也不會相互干擾,使代碼邏輯上會更加便于管理。


本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/281235.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/281235.shtml
英文地址,請注明出處:http://en.pswp.cn/news/281235.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

saltstack(三) --- salt-httpapi

以下操作均在master上操作 1. 安裝api netapi modules&#xff08;httpapi&#xff09;有三種&#xff0c;分別是rest_cherrypy、rest_tornado、rest_wsig&#xff0c;接下來要講的是rest_cherrypydoc&#xff1a;https://docs.saltstack.com/en/latest/ref/netapi/all/salt.ne…

c++實現二叉搜索樹

自己實現了一下二叉搜索樹的數據結構。記錄一下&#xff1a; #include <iostream>using namespace std;struct TreeNode{int val;TreeNode *left;TreeNode *right;TreeNode(int value) { valvalue; leftNULL; rightNULL; } };class SearchTree{public:SearchTree();~Sear…

一款自用的翻譯小工具,開源了

一款自用的翻譯小工具&#xff0c;開源了TranslationTool作者&#xff1a;WPFDevelopersOrg - 唐宋元明清|驚鏵原文鏈接&#xff1a;https://github.com/Kybs0/TranslationTool此項目使用WPF MVVM開發。框架使用大于等于.NET461。Visual Studio 2019。最初是支持以下&#xff1…

JS使用按位異或方式加密字符串

按位異或加密字符串&#xff0c;字符串加解密都是該函數 缺陷是加密密鑰使用的字符最好不要出現需要加密的字符串中的字符&#xff0c;一旦出現原字符與加密字符一樣額情況&#xff0c;異或結果為0&#xff0c;導致不能還原字符串&#xff0c;可以考慮更改算法避免這種情況 im…

SCSS 實用知識匯總

1、變量聲明 $nav-color: #F90; nav {//$width 變量的作用域僅限于{}內$width: 100px;width: $width;color: $nav-color; }.a {//報錯&#xff0c;$width未定義width: $width; } 2、父選擇器& scss代碼&#xff1a; article a {color: blue;&:hover { color: red } } 編…

【ELK集群+MQ】通用部署方案以及快速實現MQ發布訂閱服務功能

前言&#xff1a;大概一年多前寫過一個部署ELK系列的博客文章&#xff0c;前不久剛好在部署一個ELK的解決方案&#xff0c;我順便就把一些基礎的部分拎出來&#xff0c;再整合成一期文章。大概內容包括&#xff1a;搭建ELK集群&#xff0c;以及寫一個簡單的MQ服務。如果需要看一…

python容錯

#try: except: else: #為什么叫容錯呢&#xff0c;先說說錯誤&#xff0c;這里說的錯誤并不是因為馬虎或者什么原因在腳本中留下的bug&#xff0c;這個不能容掉&#xff0c;所謂容掉就是略過這個錯誤&#xff0c;要在測試時候發現并修正&#xff0c;需要容錯的錯誤是在腳本執行…

git stash參數介紹

git stash 用于暫存工作區未提交的內容&#xff0c;便于在同時開發多個分支需要切換時保存當前分支進度。 list 語法 git stash list [<options>] &#xff0c;與git log功能類似&#xff0c;列出儲藏列表&#xff0c;options 參數可以參考git log的參數 show 語法 git …

多語言報表的改動方法

在定義上傳RTF模板的時候&#xff0c;會有一個是否可翻譯的選項&#xff0c;選擇之后。就能夠上傳xlf文件作為翻譯內容。 對于已經存在的多語言類型報表&#xff0c;稍作改動之后再上傳&#xff0c;可能會出現下面現象&#xff1a; 進程出現了“未完畢”的提示 想要改動非常eas…

自定義Cell的流程

1、.h文件 // // 文 件 名:CHBackupGateWayCell.h // // 版權所有:Copyright © 2018 lelight. All rights reserved. // 創 建 者:lelight // 創建日期:2018/12/19. // 文檔說明: // 修 改 人: // 修改日期: //#import <UIKit/UIKit.h>NS_ASSUME_NONNULL_BEGINclass…

JS實時監聽DOM元素變化 - MutationObserver

使用 MutationObserver API實時監聽DOM元素變化 創建 MutationObserver 實列&#xff0c;接受一個用于監聽到DOM元素變化的回調函數 const handleListenChange (mutationsList, observer) > {console.log(mutationsList, observer) } const mutationObserver new Mutati…

LightOJ - 1027 A Dangerous Maze —— 期望

題目鏈接&#xff1a;https://vjudge.net/problem/LightOJ-1027 1027 - A Dangerous MazePDF (English)StatisticsForumTime Limit: 2 second(s)Memory Limit: 32 MBYou are in a maze; seeing n doors in front of you in beginning. You can choose any door you like. The p…

MASA MAUI Plugin (六)集成個推,實現本地消息推送[Android] 篇

背景MAUI的出現&#xff0c;賦予了廣大.Net開發者開發多平臺應用的能力&#xff0c;MAUI 是Xamarin.Forms演變而來&#xff0c;但是相比Xamarin性能更好&#xff0c;可擴展性更強&#xff0c;結構更簡單。但是MAUI對于平臺相關的實現并不完整。所以MASA團隊開展了一個實驗性項目…

第八天

配置文件 Vi /etc/fstab /dev/vg01/lv01 /dir01 ext4 defaults mount -a 掃描 使用交換空間 1.創建分區 2.mkswap /dev/sda創建交換分區 3.swapon /dev/sda啟用交換分區 Linux系統啟動過程 1、引導程序 BIOS自檢 &#xff08;硬件自檢&#xff09; 2、G…

iOS 通知中心(NSNotificationCenter)

NSNotificationCenter 在這里第一步和第二步的順序可以互換&#xff0c;一般樓主我喜歡先在需要發送消息的頁面發送消息&#xff0c;然后再在需要監聽的頁面注冊監聽。要注意的是不管是通知中心還是KVO都需要在頁面銷毀之前移除監聽。 注冊觀察者/*** 觀察者注冊消息通知*…

vue-router和react-router嵌套路由layout配置方案的區別

最近在學習react&#xff0c;在路由這一塊有點看不懂&#xff0c;第一感覺是靈活性很大&#xff0c;想怎么來就怎么來&#xff0c;但問題也來了&#xff0c;稍微復雜一點就GG了&#xff0c;不如vue的傻瓜式配置來的方便。 先說一下vue的路由配置方式&#xff0c;目錄結構如下&…

微軟加更.NET7中文手冊,都有哪些新亮點?

11月8號發布了.NET7&#xff0c;從底層性能改進&#xff0c;到上層API升級&#xff0c;讓.NET7綜合性能再度提升&#xff01;同時發布了最新的C#11&#xff0c;也帶來了很多小驚喜。如何快捷學習最新的.NET7和C#11&#xff1f;答案只有一個&#xff0c;微軟官方中文文檔&#x…

jquery對json的各種遍歷

http://caibaojian.com/jquery-each-json.html轉載于:https://www.cnblogs.com/pxffly/p/8442448.html

中級工程師之路

前言&#xff1a;之前在問答中問了一個問題 畢業半年感覺沒什么進步該怎么辦&#xff1f; 這個問題一直讓我感覺比計較焦慮。于是在一個關于面試經驗的博客中找到了一些靈感。就是通過問題進行學習&#xff0c;對自身的知識體系進行整理和補充。以問題作為切入點&#xff0c;不…

Vue在渲染函數createELement和JSX中使用插槽slot

Vue對于插槽有兩個專門的APIvm.$slots和vm.$scopedSlots&#xff0c;分別是普通插槽和作用域插槽&#xff0c;使用JSX語法或渲染函數的時候&#xff0c;定義插槽將使用上述兩個API。 渲染函數createElement 普通插槽和作用域插槽在定義上相差不大&#xff0c;但是在使用方法上…