React学习分享(四)
十、表單中的受控組件與非受控組件
1、非受控組件
React要編寫一個非受控組件,可以使用ref來從DOM節點中獲取表單數據,就是非受控組件。
例如:
因為非受控組件將真實數據儲存在DOM節點中,所以在使用非受控組件時,有時候反而更容易同時集成 React 和非 React 代碼。如果你不介意代碼美觀性,并且希望快速編寫代碼,使用非受控組件往往可以減少你的代碼量。否則,你應該使用受控組件。
在 React 渲染生命周期時,表單元素上的value將會覆蓋 DOM 節點中的值,在非受控組件中,你經常希望React能賦予組件一個初始值,但是不去控制后續的更新。 在這種情況下, 你可以指定一個defaultValue屬性,而不是 value。(defaultValue是在非受控下使用,而value是在受控的時候使用)
同樣,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的雙向數據綁定類似(v-model)
由于在表單元素上設置了value屬性,因此顯示的值將始終為this.state.value ,這使得React的state成為唯一數據源。由于handlechange在每次按鍵時都會執行并更新React的state,因此顯示的值將隨著用戶輸入而更新。
對于受控組件來說,輸入的值始終由React的state驅動。你也可以將value 傳遞給其他UI元素,或者通過其他事件處理函數重置,但這意味著你需要編寫更多的代碼。
注意: 另一種說法(廣義范圍的說法),React組件的數據渲染是否被調用者傳遞的props完全控制,控制則為受控組件,否則非受控組件。
十一、組件間通信
父子組件內通信
父組件:
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: "首頁"},{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} />{//表達式--支持函數表達式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>賣座電影</span><button style={{ float: "right" }} onClick={() => this.goHome(0)}>home</button></div></div>)}goHome = (index) => {this.props.event(index)} }這里是父組件向子組件傳遞屬性,子組件通過回調函數返回返回值,采用的是受控的方式對子組件進行控制,意思是在子組件中不過多的使用state狀態,而是通過父組件的屬性進行控制,減少組件內的狀態。
2.ref標記 (父組件拿到子組件的引用,從而調用子組件的方法)
代碼:
這里我們通過對子組件綁定ref 獲取組件中的狀態和方法,在父組件中進行對狀態和方法的改變。類似于面向對象的思想。
非父子組件內通信
1.狀態提升(中間人模式)
React中的狀態提升概括來說,就是將多個組件需要共享的狀態提升到它們最近的父組件 上.在父組件上改變這個狀態然后通過props分發給子組件??傊褪?#xff0c;我們在處理兩個兄弟組件時,可以通過回調的方式兄弟1組件把信息傳遞到父組件內,再通過props父組件傳遞到兄弟2組件,就可以收到信息了。
首先我們先看這部分代碼(發布訂閱的核心代碼):
解讀代碼:我們在一個組件中訂閱一個消息通過回調函數的方式傳遞,把每次訂閱的回調放在一個全局變量數組中,在發布中,我們去遍歷這個數組,將里面的回調函數進行執行。
案例:
js:
注意:GlobalContext.Consumer內必須是回調函數,通過context方法改變根組件狀態
context優缺點: 優點:跨組件訪問數據 缺點:react組件樹種某個上級組件shouldComponetUpdate 返回false,當context更新時,不 會引起下級組件更新
十二、插槽
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>)} }這里通過this.props.children來獲取寫在組件里面的東西
如果里面的東西想要獲取多個div,也可以寫成數據this.props.children[0],this.props.children[1]這樣來得到,如果不寫成數組this.props.children,則是獲得到全部的div。
作用:
總結
以上是生活随笔為你收集整理的React学习分享(四)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 急!2022年底前需实现电子发票无纸化报
- 下一篇: CDOJ 1144 Big Brothe