赞
踩
1、传递方式与函数组件一致
2、接收时通过 this.props.mes 获取
import React from 'react' class Son extends React.PureComponent{ render() { return ( <> <h3>子组件</h3> {/* 2、接收 */} <span>接收:{this.props.mes}</span> </> ) } } class App extends React.PureComponent { state = { sonMes:'son' } render() { return ( <div> <h2>父组件</h2> {/* 1、传递 */} <Son mes={ this.state.sonMes} /> </div> ) } } export default App;
1、手写验证方法
2、借助 proptypes 库
// 1、props 类型限制 Son.propTypes = { // (1)手写 mes: function (props) { if (typeof props.mes !== 'string') { throw new Error('mes 必须为字符串') } }, // (2)使用库 color:proptypes.number } // 2、props 默认值限制 Son.defaultProps = { mes: '默认值', color:'绿色' }
传递html元素,借助【props.children】获取
1、传递:写在子组件内容区域
2、接收: this.props.children
import React from 'react' class Son extends React.PureComponent{ render() { return ( <> {/* 2、接收 */} <span>接收:{this.props.children}</span> </> ) } } class App extends React.PureComponent { render() { return ( <div> {/* 1、传递 */} <Son> <li>内容</li> <li>内容</li> <li>内容</li> </Son> </div> ) } } export default App;
1、父组件传递函数,函数返回值为html元素
2、子组件调用时,传递数据,渲染jsx
import React from 'react' class Son extends React.PureComponent{ state = { data:'作用域插槽' } render() { return ( <> {/* 2、接收 */} {/* 作用域插槽 */} {this.props.slot(this.state.data)} </> ) } } class App extends React.PureComponent { render() { return ( <div> {/* 1、传递 */} <Son slot={(slot) => <div>{ slot}</div>}></Son> </div> ) } } export default App;
1、父组件向子组件传递方法
2、子组件调用并传递数据
3、父组件拿到数据
import React from 'react' class Son extends React.PureComponent{ state = { data:'作用域插槽' } render() { return ( <> {/* 2、子组件调用并传递数据 */} <button onClick={() => { this.props.onActive('data') }}> 点击传递 </button> </> ) } } class App extends React.PureComponent { // 3、父组件拿到数据 handle = (data) => { console.log('接收数据',data); } render() { return ( <div> {/* 1、父组件向子组件传递方法 */} <Son onActive={this.handle} /> </div> ) } } export default App;
0、渲染 render
初次渲染 更新时执行
1、挂载 componentDidMount
(1)数据请求
(2)echart绘制
2、更新
shouldComponentUpdate(是否更新)
性能优化 PureComponent
componentDidUpdate
3、卸载 componentDidUnmount
销毁定时器
1、vue
(1)使用了【get】依赖收集,把受当前数据影响的部分收集起来
(2)数据变动时使用【set】触发更新
2、react
(1)使用useState触发更新,无论数据是否改变
(2)有性能问题
1、用于获取DOM节点或者组件实例
2、获取组件时,只能获取类组件,函数组件没有实例
3、在挂载阶段获取ref
import React from 'react' // 1、声明标识变量 let identify = React.createRef() let son = React.createRef() class Son extends React.Component { f1 = () => { console.log('调用子组件的方法'); } render() { return <div>子组件</div> } } class App extends React.Component { componentDidMount() { // 3、获取DOM console.log(identify.current); console.log(son.current); son.current.f1() } render() { return ( // 2、打标识 <div ref={identify}><Son ref={son}/></div> ) } } export default App;
ref={(c)=>{this.input1=c}}
1、c 实际上为当前DOM实例
2、将 c 挂载到this上
3、并取名为 input1
4、这样便可以通过this.input1 拿到该 DOM
class Demo extends React.Component{ //展示左侧输入框的数据 showData = ()=>{ const {input1} = this alert(input1.value) } //展示右侧输入框的数据 showData2 = ()=>{ const {input2} = this alert(input2.value) } render(){ return( <div> <input ref={(a)=>{this.input1=a}} type="text" placeholder="点击按钮提示数据"/> <button onClick={this.showData}>点我提示左侧的数据</button> <input onBlur={this.showData2} ref={c => this.input2 = c } type="text" placeholder="失去焦点提示数据"/> </div> ) } }
适用于跨级组件通信
1、声明公用的context组件
2、传递方:provider
3、接收方:
(1) consumer组件 + 作用域插槽
(2) 静态属性contextType + this.context
import React from 'react' // 1、声明context变量 let Context = React.createContext() class GrandSon extends React.Component { // 指定 contextType 读取 context static contextType = Context; render() { return ( <> <h4>孙子组件</h4> {/* 3、使用方 */} {/* (1):consumer + 作用域插槽 */} <Context.Consumer> {(value) => <div>{ value}</div>} </Context.Consumer> {/* (2) 借助静态属性 使用 this.context 访问 */} <div>{this.context}</div> </> ) } } class Son extends React.Component { render() { return ( <div> <h3>子组件</h3> <GrandSon/> </div> ) } } class App extends React.Component { state = { data: 'context 传递的数据' } render() { return ( <> <h2>父组件</h2> {/* 2、传递方:provide并传递value */} <Context.Provider value={this.state.data}> <Son /> </Context.Provider> </> ) } } export default App;
1、让函数组件也可以有state状态, 并进行状态数据的读写操作
2、【语法】:
const [xxx, setXxx] = React.useState(initValue)
3、useState()说明:
【参数】: 第一次初始化指定的值在内部作缓存
【返回值】: 包含2个元素的数组, 第1个为内部当前状态值, 第2个为更新状态值的函数
4、setXxx()2种写法:
setXxx(newValue): 参数为非函数值, 直接指定新的状态值, 内部用其覆盖原来的状态值
setXxx(value => newValue): 参数为函数, 接收原本的状态值, 返回新的状态值, 内部用其覆盖原来的状态值
1、在函数组件中执行副作用操作(用于模拟类组件中的生命周期钩子) 2、React中的副作用操作: 发ajax请求数据获取 设置订阅 / 启动定时器 手动更改真实DOM 3、语法和说明: useEffect(() => { // update/mount return () => { // 在组件卸载前执行 // 在此做一些收尾工作, 比如清除定时器/取消订阅等 } }, [stateValue]) // 如果指定的是[], 回调函数只会在第一次render()后执行 4、可以把 useEffect Hook 看做如下三个函数的组合 componentDidMount() componentDidUpdate() componentWillUnmount() 5、第二个参数填写依赖项 类似于【vue的监听】
1、用于优化函数组件性能,缓存【数据】,避免不必要的计算
2、相当于 vue 的【计算属性】
3、根据依赖项决定是否重新计算
1、用于优化函数组件性能,缓存【函数】,避免不必要的计算
2、相当于 vue 的【计算属性】
3、根据依赖项决定是否重新计算
0、与【createRef】类似,只是声明标识变量的方式不同
1、用来获取DOM阶段
2、用来获取之前的数据
3、用来获取组件及组件身上的方法
1、创建context方式不变
const Context = React.createContext()
2、【使用方】useContext 直接接收值
let value = useContext(Context)
【用途】提取公用逻辑,实现复用
1、问题:父组件的更新会连带子组件一起更新
2、解决:diff算法 + 时间切片(部分更新,部分渲染)
(1) 将任务分为许多个执行单元
(2) 有时间 ? 接着运行执行单元 :交给浏览器更新
3、引入fiber数据结构
为了支持切片,引入此数据结构
(1) 支持组件切片
(2) 具有继续执行的能力(恢复上次进度)
4、我们能做的
(1) PureComponment
避免state修改为同样的值,触发更新
(2) Memo 结合 useMemo 、useCallback
包裹对象、数组、方法 避免子组件更新
Ant Design
1、Button
2、Table 插槽
3、定制主题 ConfigProvider
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。