React---day6、7
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会拆卸原有的树,并且建立起新的树:
- 当一个元素从 变成 ,从
变成 ,或从 变成 都会触发一个完整的重建流程;相关文章:
- hook组件-useEffect、useRef
- 功能结构整理
- 企业级开发中的 maven-mvnd 应用实践
- yolov12毕设前置知识准备 1
- 随机游动算法解决kSAT问题
- 《Discuz! X3.5开发从入门到生态共建》第1章 Discuz! 的前世今生-优雅草卓伊凡
- azure web app创建分步指南系列之一
- PyTorch实战——基于生成对抗网络生成服饰图像
- 笔试强训:Day6
- 【Hexo】4.Hexo 博客文章进行加密
- Android --- ObjectAnimator 和 TranslateAnimation有什么区别
- 小白的进阶之路系列之四----人工智能从初步到精通pytorch自定义数据集下
- 安卓添加设备节点权限和selinux访问权限
- 谷歌Stitch:AI赋能UI设计,免费高效新利器
- 运营商地址和ip属地一样吗?怎么样更改ip属地地址
- 在QT中,利用charts库绘制FFT图形
- ChatGPT + 知网 + 知乎,如何高效整合信息写出一篇专业内容?
- 流媒体协议分析:流媒体传输的基石
- vscode中让文件夹一直保持展开不折叠
- JAVA-springboot整合Mybatis
- 深度学习pycharm debug
- MicroPython+L298N+ESP32控制电机转速
- Hive的存储格式如何优化?
- 在部署了一台mysql5.7的机器上部署mysql8.0.35
- OpenCV CUDA模块结构分析与形状描述符------在 GPU 上计算图像的原始矩(spatial moments)函数spatialMoments()
- QT入门学习(一)---新建工程与、信号与槽
- UE5.4.4+Rider2024.3.7开发环境配置
- Windows环境下PHP,在PowerShell控制台输出中文乱码
- 第2篇:数据库连接池原理与自定义连接池开发实践
- 性能优化 - 理论篇:性能优化的七类技术手段