React学习分享(四)
十、表單中的受控組件與非受控組件
1、非受控組件
React要編寫(xiě)一個(gè)非受控組件,可以使用ref來(lái)從DOM節(jié)點(diǎn)中獲取表單數(shù)據(jù),就是非受控組件。
例如:
因?yàn)榉鞘芸亟M件將真實(shí)數(shù)據(jù)儲(chǔ)存在DOM節(jié)點(diǎn)中,所以在使用非受控組件時(shí),有時(shí)候反而更容易同時(shí)集成 React 和非 React 代碼。如果你不介意代碼美觀性,并且希望快速編寫(xiě)代碼,使用非受控組件往往可以減少你的代碼量。否則,你應(yīng)該使用受控組件。
在 React 渲染生命周期時(shí),表單元素上的value將會(huì)覆蓋 DOM 節(jié)點(diǎn)中的值,在非受控組件中,你經(jīng)常希望React能賦予組件一個(gè)初始值,但是不去控制后續(xù)的更新。 在這種情況下, 你可以指定一個(gè)defaultValue屬性,而不是 value。(defaultValue是在非受控下使用,而value是在受控的時(shí)候使用)
同樣,checkbox radio支持defaultChecked,select和textarea支持defaultValue
1、受控組件
import React, { Component } from 'react' export default class App extends Component {state = {mytext: "123"}render() {return (<div><input type="text" value={this.state.mytext} onChange={(e) => {this.setState({mytext: e.target.value})}} /><button onClick={() => {console.log(this.state.mytext);}}>獲取Value</button><button onClick={() => {this.setState({mytext: ""})}}>重置</button></div>)} }原理和vue的雙向數(shù)據(jù)綁定類(lèi)似(v-model)
由于在表單元素上設(shè)置了value屬性,因此顯示的值將始終為this.state.value ,這使得React的state成為唯一數(shù)據(jù)源。由于handlechange在每次按鍵時(shí)都會(huì)執(zhí)行并更新React的state,因此顯示的值將隨著用戶輸入而更新。
對(duì)于受控組件來(lái)說(shuō),輸入的值始終由React的state驅(qū)動(dòng)。你也可以將value 傳遞給其他UI元素,或者通過(guò)其他事件處理函數(shù)重置,但這意味著你需要編寫(xiě)更多的代碼。
注意: 另一種說(shuō)法(廣義范圍的說(shuō)法),React組件的數(shù)據(jù)渲染是否被調(diào)用者傳遞的props完全控制,控制則為受控組件,否則非受控組件。
十一、組件間通信
父子組件內(nèi)通信
父組件:
import React, { Component } from 'react' import './css/01-maizuo.css' import Home from "./compontents/home" import Cinema from "./compontents/cinema" import My from "./compontents/My" import Tabbar from './compontents/Tabbar' import Navbar from './compontents/Navbar' export default class APP extends Component {state = {list: [{id: 0,text: "首頁(yè)"},{id: 1,text: "電影"},{id: 2,text: "我的"}],current: 0}switch() {switch (this.state.current) {case 0:return <Home></Home>case 1:return <Cinema></Cinema>case 2:return <My></My>default:return null}}render() {return (<div><Navbar event={this.tarrget} />{//表達(dá)式--支持函數(shù)表達(dá)式this.switch()}<Tabbar current={this.state.current} list={this.state.list} event={this.tarrget}></Tabbar></div>)}tarrget = (index) => {this.setState({current: index})} }子組件Tabbar:
import React, { Component } from 'react' export default class Tabbar extends Component {render() {return (<div><div><ul>{this.props.list.map((item, index) =><li key={item.id} className={this.props.current === index ? 'active' : ''} onClick={() => this.click(index)}>{item.text}</li>)}</ul></div></div>)}click = (index) => {this.props.event(index)} }子組件Navbar:
import React, { Component } from 'react' export default class Navbar extends Component {render() {return (<div><div style={{ background: "yellow", textAlign: "center", overflow: "hidden" }}><button style={{ float: "left" }}>back</button><span>賣(mài)座電影</span><button style={{ float: "right" }} onClick={() => this.goHome(0)}>home</button></div></div>)}goHome = (index) => {this.props.event(index)} }這里是父組件向子組件傳遞屬性,子組件通過(guò)回調(diào)函數(shù)返回返回值,采用的是受控的方式對(duì)子組件進(jìn)行控制,意思是在子組件中不過(guò)多的使用state狀態(tài),而是通過(guò)父組件的屬性進(jìn)行控制,減少組件內(nèi)的狀態(tài)。
2.ref標(biāo)記 (父組件拿到子組件的引用,從而調(diào)用子組件的方法)
代碼:
這里我們通過(guò)對(duì)子組件綁定ref 獲取組件中的狀態(tài)和方法,在父組件中進(jìn)行對(duì)狀態(tài)和方法的改變。類(lèi)似于面向?qū)ο蟮乃枷搿?/p>
非父子組件內(nèi)通信
1.狀態(tài)提升(中間人模式)
React中的狀態(tài)提升概括來(lái)說(shuō),就是將多個(gè)組件需要共享的狀態(tài)提升到它們最近的父組件 上.在父組件上改變這個(gè)狀態(tài)然后通過(guò)props分發(fā)給子組件。總之就是,我們?cè)谔幚韮蓚€(gè)兄弟組件時(shí),可以通過(guò)回調(diào)的方式兄弟1組件把信息傳遞到父組件內(nèi),再通過(guò)props父組件傳遞到兄弟2組件,就可以收到信息了。
首先我們先看這部分代碼(發(fā)布訂閱的核心代碼):
解讀代碼:我們?cè)谝粋€(gè)組件中訂閱一個(gè)消息通過(guò)回調(diào)函數(shù)的方式傳遞,把每次訂閱的回調(diào)放在一個(gè)全局變量數(shù)組中,在發(fā)布中,我們?nèi)ケ闅v這個(gè)數(shù)組,將里面的回調(diào)函數(shù)進(jìn)行執(zhí)行。
案例:
js:
注意:GlobalContext.Consumer內(nèi)必須是回調(diào)函數(shù),通過(guò)context方法改變根組件狀態(tài)
context優(yōu)缺點(diǎn): 優(yōu)點(diǎn):跨組件訪問(wèn)數(shù)據(jù) 缺點(diǎn):react組件樹(shù)種某個(gè)上級(jí)組件shouldComponetUpdate 返回false,當(dāng)context更新時(shí),不 會(huì)引起下級(jí)組件更新
十二、插槽
import React, { Component } from 'react' class Child extends Component{render(){return <div>child{/* 插槽 vue slot,具名插槽 */}{this.props.children[2]}{this.props.children[1]}{this.props.children[0]}</div>} } class Swiper extends Component{render(){return <div>{this.props.children}</div>} } export default class App extends Component {render() {return (<div><Swiper><div>111111</div><div>222222</div><div>333333</div></Swiper><Child><div>11111111</div><div>22222222</div><div>33333333</div></Child></div>)} }這里通過(guò)this.props.children來(lái)獲取寫(xiě)在組件里面的東西
如果里面的東西想要獲取多個(gè)div,也可以寫(xiě)成數(shù)據(jù)this.props.children[0],this.props.children[1]這樣來(lái)得到,如果不寫(xiě)成數(shù)組this.props.children,則是獲得到全部的div。
作用:
總結(jié)
以上是生活随笔為你收集整理的React学习分享(四)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 急!2022年底前需实现电子发票无纸化报
- 下一篇: CDOJ 1144 Big Brothe