6、組件之間進行數據傳遞
**6.1 父傳子:**props傳遞屬性
父組件:
<div><ChildCpn name="蔣乙菥" age="18" height="1,88" />
</div>
子組件:
export class ChildCpn extends React.Component{render(){const {name , age , height} = this.propsreturn (<div><h2>{"姓名" + name + "," + "年齡" + age + "身高" + height}</h2></div>)}}
**6.2 子傳父:**父組件定義函數,子組件調用函數
父組件:
<BtnCpn addNum={this.addNum.bind(this)}/>addNum() {this.setState({num : this.state.num + 1})}
子組件:
import React from "react";export class BtnCpn extends React.Component{render(){const { addNum } = this.propsreturn (<div onClick={addNum}>+1</div>)}
}
但是我們也出現了this的綁定問題:
子傳父通信.js:22 Uncaught TypeError: Cannot read properties of undefined (reading 'setState')at addNum (子傳父通信.js:22:1)
nind綁定
<BtnCpn addNum={this.addNum.bind(this)}/>
箭頭函數:
addNumTwo = () => {this.setState({num : this.state.num + 1})//箭頭函數}
6.3 階段案例
由兩部分組成:tabBar以及父組件
父組件傳遞數據給子組件,點擊子組件,傳遞數據給父組件,切換內容
App.js
import React from "react";
import { TabBar } from "./tabBar";
export class App extends React.Component{constructor(){super();this.state = {tabList : ["流行" , "新款" , "精選"],context : "流行",curIndex: 0}}render(){return (<div className="content"><TabBar clickItem={this.handleTabClick}curIndex={this.state.curIndex}tabList={this.state.tabList} /><h2>{this.state.context}</h2></div>)}handleTabClick = (index) => {this.setState({curIndex: index,context: this.state.tabList[index]});//更改的函數}}
tabBar
import React from "react";
export class TabBar extends React.Component{render(){const {tabList , curIndex , clickItem } = this.props;return (<ul className="tab">{tabList.map((item, index) => (<likey={index}className={`item${curIndex === index ? ' active' : ''}`}onClick={() => clickItem(index)}>{item}</li>))}</ul>)}
}
6.4 跨組件通信
context相關的api
React.createContext
用于創建一個 Context 對象。當 React 渲染一個訂閱了這個 Context 的組件時,它會從組件樹中最近的 Provider 中讀取當前的 context 值。
Context.Provider
每個 Context 對象都會有一個 Provider React 組件,它允許消費組件訂閱 context 的變化。
Class.contextType
用于 class 組件中訂閱 Context,只有當組件中使用了 contextType
,組件才會訂閱 Context 的變化。
Context.Consumer
用于函數式組件中訂閱 Context。它允許你訂閱 context 的變化,并在 context 發生變化時重新渲染組件。
useContext
Hook
用于函數式組件中訂閱 Context。它接收一個 context 對象(從 React.createContext
創建)并返回該 context 的當前值。
實例:
import React, { createContext, useContext } from 'react';// 創建一個 Context 對象
const ThemeContext = createContext('light');// 一個函數式組件,使用 useContext 訂閱 Context
function ThemedButton() {const theme = useContext(ThemeContext);return <button style={{ background: theme === 'dark' ? 'black' : 'white', color: theme === 'dark' ? 'white' : 'black' }}>I am styled by theme!</button>;
}// 一個中間組件
function Toolbar() {return (<ThemedButton />);
}// 應用程序的頂層組件
function App() {return (<ThemeContext.Provider value="dark"><Toolbar /></ThemeContext.Provider>);
}export default App;
7、slot插槽
其實也算是傳參數叭,只是參數是html表達式
App.js
<NavBar2 leftSlot={<span>aaa</span>} centerSlot={<span>bbb</span>}rightSlot={<span>ccc</span>}/>
NavBar2:
export class NavBar2 extends React.Component {render() {const {leftSlot , centerSlot , rightSlot } = this.props;return (<div className="main"><div className="bay-left">{leftSlot}</div><div className="bay-mid">{centerSlot}</div><div className="bay-right">{rightSlot}</div></div>)}
}
8、setState
8.1 為什么要使用setState?
- 開發中我們并不能直接通過修改state的值來讓界面發生更新:
- 因為我們修改了state之后,希望React根據最新的State來重新渲染界面,但是這種方式的修改React并不知道數據發生了變化;
- React并沒有實現類似于Vue2中的Object.defineProperty或者Vue3中的Proxy的方式來監聽數據的變化;
- 我們必須通過setState來告知React數據已經發生了變化;
8.2 為什么可以直接this.setState
setState方法是從Component中繼承過來的。
8.3 為什么setState是異步的
- setState設計為異步,可以顯著的提升性能;
-
- 如果每次調用 setState都進行一次更新,那么意味著render函數會被頻繁調用,界面重新渲染,這樣效率是很低的;
- 最好的辦法應該是獲取到多個更新,之后進行批量更新;
- 如果同步更新了state,但是還沒有執行render函數,那么state和props不能保持同步;
-
- ? state和props不能保持一致性,會在開發中產生很多的問題;
8.4 setState一定是異步的嗎
- 在組件生命周期或React合成事件中,setState是異步;
- 在setTimeout或者原生dom事件中,setState是同步
8.5 數據的合并
當this.state里面有兩個屬性:name、title
我們修改只修改name,那么title會不會受到影響呢?答案是不會
源碼中其實是有對 原對象 和 新對象進行合并的:
Object.assign
setState可以傳入參數或者是函數:
傳入參數:數據會進行合并,多個setSEtate合并更新為1個
傳入函數:數據不會進行合并
最后會+3
9、React的更新流程
更新優化的方法:
9.1 對比不同類型的元素
當節點為不同的元素,React會拆卸原有的樹,并且建立起新的樹:
- 當一個元素從 變成 ,從
變成 ,或從 變成 都會觸發一個完整的重建流程;
本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。 如若轉載,請注明出處:http://www.pswp.cn/pingmian/83591.shtml 繁體地址,請注明出處:http://hk.pswp.cn/pingmian/83591.shtml 英文地址,請注明出處:http://en.pswp.cn/pingmian/83591.shtml
如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!