日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

React学习笔记(二) | 受控组件

發布時間:2024/1/8 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 React学习笔记(二) | 受控组件 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

React組件

目標

  • 能夠知道受控組件是什么
  • 能夠寫出受控組件
  • 了解非受控組件

表單處理

受控組件(★★★)

  • HTML中的表單元素是可輸入的,也就是有自己的可變狀態
  • 而React中可變狀態通常保存在state中,并且只能通過setState() 方法來修改
  • React講state與表單元素值value綁定在一起,有state的值來控制表單元素的值
  • 受控組件:值受到react控制的表單元素

使用步驟

  • 在state中添加一個狀態,作為表單元素的value值
  • 給表單元素綁定change事件,將表單元素的值設置為state的值

示例demo

class App extends React.Component {constructor(){super()this.inputChange = this.inputChange.bind(this)}state = {txt : ''}inputChange(e){this.setState({txt: e.target.value})}render(){console.log(this.state);return (<div>{/* 把state的值設置給輸入框的value,綁定change事件,這樣用戶在輸入內容的時候調用相應函數,在函數里面把當前設置的值賦值給state,從而達到數據的統一 */}<input type="text" value={this.state.txt} onChange={this.inputChange}/></div>)} } ReactDOM.render(<App />,document.getElementById('root'))

多表單元素優化

  • 問題:每個表單元素都有一個單獨的事件處理函數,這樣太繁瑣
  • 優化:使用一個事件處理程序同時處理多個表單元素
步驟
  • 給表單元素添加name屬性(用來區分是哪一個表單),名稱與state相同(用來更新數據的)
  • 根據表單內容來獲取對應值
  • 在change事件處理程序中通過 [name] 來修改對應的state
示例demo
inputChange(e){let target = e.target;let value = target.type == 'checkbox' ? target.checked : target.value;this.setState({[e.target.name]: value}) } <input type="text" value={this.state.txt} name="txt" onChange={this.inputChange}/> <input type="checkbox" value={this.state.isChecked} name="isChecked" onChange={this.inputChange}/>

非受控組件 (了解)

  • 說明:借助于ref,使用元素DOM方式獲取表單元素值
  • ref的作用:獲取DOM或者組件

使用步驟

  • 調用 React.createRef() 方法創建ref對象
  • 將創建好的 ref 對象添加到文本框中
  • 通過ref對象獲取到文本框的值
class App extends React.Component {constructor(){super()//創建 refthis.txtRef = React.createRef()}// 獲取文本框的值getTxt =() => {console.log(this.txtRef.current.value)}render(){return (<div><input type ="text" ref={this.txtRef} /><button onClick ={this.getTxt}>獲取值</button></div>)} }

React組件綜合案例(★★★)

需求分析

  • 渲染評論列表(列表渲染)
  • 沒有評論數據時渲染:暫無評論(條件渲染)
  • 獲取評論信息,包括評論人和評論內容(受控組件)
  • 發表評論,更新評論列表(setState())

搭建評論列表的模板

  • 結構
import React from 'react' import ReactDOM from 'react-dom'/* 評論列表案例comments: [{ id: 1, name: 'jack', content: '沙發!!!' },{ id: 2, name: 'rose', content: '板凳~' },{ id: 3, name: 'tom', content: '樓主好人' }] */import './index.css'class App extends React.Component {render() {return (<div className="app"><div><input className="user" type="text" placeholder="請輸入評論人" /><br /><textareaclassName="content"cols="30"rows="10"placeholder="請輸入評論內容"/><br /><button>發表評論</button></div><div className="no-comment">暫無評論,快去評論吧~</div><ul><li><h3>評論人:jack</h3><p>評論內容:沙發!!!</p></li></ul></div>)} }// 渲染組件 ReactDOM.render(<App />, document.getElementById('root'))
  • 樣式
.app {width: 300px;padding: 10px;border: 1px solid #999; }.user {width: 100%;box-sizing: border-box;margin-bottom: 10px; }.content {width: 100%;box-sizing: border-box;margin-bottom: 10px; }.no-comment {text-align: center;margin-top: 30px; }

渲染評論列表

  • 在state中初始化評論列表數據
state = {comments: [{ id: 1, name: 'jack', content: '沙發!!!' },{ id: 2, name: 'rose', content: '板凳~' },{ id: 3, name: 'tom', content: '樓主好人' }]}
  • 使用數組的map方法遍歷state中的列表數據
  • 給每一個被遍歷的li元素添加key屬性
  • 在render方法里的ul節點下嵌入表達式
{this.state.comments.map(item => {return (<li key={item.id}><h3>{item.name}</h3><p>{item.content}</p></li>)}) }

渲染暫無評論

  • 判斷列表數據的長度是否為0

  • 如果為0,則渲染暫無評論

  • 如果不為0,那么渲染列表數據

  • 在jsx中大量寫邏輯會導致很臃腫,所以我們可以把條件渲染的邏輯抽取成一個函數

/*** 條件渲染,這里抽取出來了,這樣在結構中不會很混亂*/ renderList(){if (this.state.comments.length === 0) {return (<div className="no-comment">暫無評論,快去評論吧~</div>)} else {return (<ul> {this.state.comments.map(item => {return (<li key={item.id}><h3>{item.name}</h3><p>{item.content}</p></li>)})}</ul>)} }
  • 在render的return方法里面調用這個函數即可
render() {return (<div>...{/* 通過條件渲染來判斷是否顯示暫無評論 */}{this.renderList()}</div>) }

獲取評論信息

  • 通過受控組件來獲取內容
  • 初始化用戶名和用戶內容的state
userName: '', userContent: ''
  • 在結構中,把表單元素的value與state進行綁定,還需要綁定name屬性和onChange屬性
<input className="user" type="text" placeholder="請輸入評論人" value={this.state.userName} name="userName" onChange={this.handleForm}/> <br /> <textareaclassName="content"cols="30"rows="10"placeholder="請輸入評論內容"value={this.state.userContent}name="userContent"onChange={this.handleForm} />
  • 在handleFrom函數中利用setState來讓數據保持一致
handleForm = (e) => {this.setState({[e.target.name] : e.target.value})}

發表評論

  • 給按鈕綁定事件
  • 在事件處理程序中,通過state獲取評論信息
  • 將評論信息添加到state中,利用setState來更新頁面
  • 添加評論前需要判斷用戶是否輸入內容
  • 添加評論后,需要情況文本框用戶輸入的值
handleClick = (e) => {// 拿到用戶輸入的內容let {userName,userContent} = this.stateif(userName.trim()==='' || userContent.trim() === ''){alert('請輸入內容')return}// 利用數組拓展運算符來進行數據的拼接,把用戶輸入的存放在數組的第一個位置let newComments = [{id: this.state.comments.length+1,name: userName,content: userContent},...this.state.comments]this.setState({comments: newComments,userName:'',userContent: ''}) }

React組件進階

目標

  • 能夠使用props接收數據
  • 能夠實現父子組件之間的通訊
  • 能夠實現兄弟組件之間的通訊
  • 能夠給組件添加props校驗

組件通訊介紹

組件是獨立且封閉的單元,默認情況下,只能使用組件自己的數據。在組件化過程中,我們將一個完整的功能拆分成多個組件,以更好的完成整個應用的功能。而在這個過程中,多個組件之間不可避免的要共享某些數據。為了實現這些功能,就需要打破組件的獨立封閉性,讓其與外界溝通,這個過程就是組件通訊

組件的props(★★★)

基本使用

  • 組件時封閉的,要接受外部數據應該通過props來實現
  • props的作用:接收傳遞給組件的數據
  • 傳遞數據:給組件標簽添加屬性

  • 接收數據:函數組件通過 參數 props接收數據,類組件通過 this.props接收數據

    • 函數組件獲取

    • 類組件獲取

?

特點

  • 可以給組件傳遞任意類型的數據
  • props是只讀屬性,不能對值進行修改
  • 注意:使用類組件時,如果寫了構造函數,應該將props傳遞給super(),否則,無法在構造函數中獲取到props,其他的地方是可以拿到的

組件通訊的三種方式(★★★)

父組件傳遞數據給子組件

  • 父組件提供要傳遞的state數據
  • 給子組件標簽添加屬性,值為state中的數據
  • 子組件中通過props接收父組件中傳遞的數據

子組件傳遞數據給父組件

  • 利用回調函數,父組件提供回調,子組件調用,將要傳遞的數據作為回調函數的參數
  • 父組件提供一個回調函數,用來接收數據
  • 將該函數作為屬性的值,傳遞給子組件

  • 子組件通過props調用回調函數

兄弟組件傳遞

  • 將共享狀態(數據)提升到最近的公共父組件中,由公共父組件管理這個狀態
  • 這個稱為狀態提升
  • 公共父組件職責:1. 提供共享狀態 2.提供操作共享狀態的方法
  • 要通訊的子組件只需要通過props接收狀態或操作狀態的方法

示例demo

  • 定義布局結構,一個Counter里面包含兩個子組件,一個是計數器的提示,一個是按鈕
class Counter extends React.Component {render() {return (<div><Child1 /><Child2 /></div>)} } class Child1 extends React.Component {render() {return (<h1>計數器:</h1>)} } class Child2 extends React.Component {render() {return (<button>+1</button>)} }
  • 在父組件里定義共享狀態,把這個狀態傳遞給第一個子組件
class Counter extends React.Component {// 提供共享的狀態state = {count: 0}render() {return (<div>{/* 把狀態提供給第一個子組件 */}<Child1 count={this.state.count}/><Child2 /></div>)} }
  • 在第一個子組件里面就能通過props獲取到
class Child1 extends React.Component {render() {return (<h1>計數器:{this.props.count}</h1>)} }
  • 在父組件中提供共享方法,通過屬性傳遞給第二個子組件,方便第二個子組件來進行調用
// 提供共享方法onIncrement = (res) => {// 只要第二個子組件調用了這個函數,就會執行里面代碼this.setState({count: this.state.count + res})}render() {return (<div>...{/* 把共享方法提供給第二個子組件 */}<Child2 onIncrement={this.onIncrement} /></div>)}
  • 在第二個子組件里面通過props來獲取到對應函數,然后進行調用
class Child2 extends React.Component {handleClick = () => {// 這里一旦調用,就會執行父組件里面 onIncrement函數this.props.onIncrement(2)}render() {return (<button onClick={this.handleClick}>+</button>)} }

Context(★★★)

如果出現層級比較多的情況下(例如:爺爺傳遞數據給孫子),我們會使用Context來進行傳遞

作用: 跨組件傳遞數據

使用步驟

  • 調用 React.createContext() 創建 Provider(提供數據) 和 Consumer(消費數據) 兩個組件

  • 使用Provider 組件作為父節點

  • 設置value屬性,表示要傳遞的數據

  • 哪一層想要接收數據,就用Consumer進行包裹,在里面回調函數中的參數就是傳遞過來的值

小結

  • 如果兩個組件相隔層級比較多,可以使用Context實現組件通訊
  • Context提供了兩個組件:Provider 和 Consumer
  • Provider組件: 用來提供數據
  • Consumer組件: 用來消費數據

props進階

children屬性

  • children屬性: 表示組件標簽的子節點,當組件標簽有子節點時,props就會有該屬性
  • children屬性與普通的props一樣,值可以使任意值(文本、react元素、組件、甚至是函數)

props校驗(★★★)

  • 對于組件來說,props是外來的,無法保證組件使用者傳入什么格式的數據,簡單來說就是組件調用者可能不知道組件封裝著需要什么樣的數據
  • 如果傳入的數據不對,可能會導致報錯
  • 關鍵問題:組件的使用者不知道需要傳遞什么樣的數據
  • props校驗:允許在創建組件的時候,指定props的類型、格式等

  • 作用:捕獲使用組件時因為props導致的錯誤,給出明確的錯誤提示,增加組件的健壯性

使用步驟

  • 安裝包 prop-types (yarn add prop-types | npm i props-types)
  • 導入prop-types 包
  • 使用組件名.propTypes={} 來給組件的props添加校驗規則
  • 校驗規則通過PropTypes對象來指定

常見的約束規則

  • 創建的類型: array、bool、func、number、object、string
  • React元素類型:element
  • 必填項:isRequired
  • 特定結構的對象: shape({})
  • 更多的約束規則

props的默認值

  • 場景:分頁組件 -> 每頁顯示條數

總結

以上是生活随笔為你收集整理的React学习笔记(二) | 受控组件的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。