本文目录
1. setStatesetState更新状态的2种写法
2.lazyLoad路由组件的lazyLoad
3. Fragment使用作用
4.createContext()理解使用示例注意

本文被专栏【React–从基础到实战】收录

坚持创作️,一起学习,码出未来‍!

1. setState
setState更新状态的2种写法

(1). setState(stateChange, [callback]) —–对象式的setState
this.setState({ count: count + 1 }, () => {
// render调用后
console.log(this.state.count)
});
1234
stateChange为状态改变对象,该对象可以体现出状态的更改;callback是可选的回调函数,它在状态更新完毕,页面也更新后(render调用后)才被调用

(2). setState(updater, [callback]) —– 函数式的setState
this.setState((state, props) => {
console.log(state, props)
return { count: state.count + 1 }
});
1234
updater为返回stateChange对象的函数;updater可以接收到state和props;callback是可选的回调函数,它在状态更新、页面也更新后(render调用后)才被调用

总结:
对象式的setState是函数式的setState的简写方式(语法糖) 使用原则: (1)如果新状态不依赖于原状态 ==== 使用对象方式 (2)如果新状态依赖于原状态 ==== 使用函数方式 (3)如果需要在setState()执行后获取最新的状态数据,要在第二个callback函数中读取 React状态的更新是异步的!!

2.lazyLoad
路由组件的lazyLoad
引入lazy函数和Suspense组件
import React, { Component, lazy, Suspense } from ‘react’
1
实现路由懒加载
// 1.通过React的lazy函数配合import()函数动态加载路由组件 ===> 路由组件代码会被分开打包
const Login = lazy(() => import(‘@/pages/Login’))

// 2. 通过<Suspense>指定在加载得到路由打包文件前显示一个自定义loading界面
<Suspense fallback={<h1>loading</h1>}>
<Switch>
<Route path=”/xxx” component={xxx}/>
<Redirect to=”/login”/>
</Switch>
</Suspense>
12345678910
3. Fragment
使用

// Componment
import React, { Component, Fragment } from ‘react’
import Demo from ‘./components/4_fragment’

export default class App extends Component {
render() {
return (
<Fragment>
<Demo />
</Fragment>
)
}
}

// FC
import React, { Fragment } from ‘react’

export default function Demo() {
return (
<Fragment>
<input type=”text” />
<input type=”text” />
</Fragment>
)
}
其实还可以…
import React from ‘react’

export default function Demo() {
return (
<>
<input type=”text” />
<input type=”text” />
</>
)
}

12345678910111213141516171819202122232425262728293031323334353637
作用

可以不用必须有一个真实的DOM根标签了

4.createContext()
理解

一种组件间通信方式,常用于【祖组件】与【后代组件】间通信

使用

创建Context容器对象: const Xxxcontext = React.createContext()例如:进口气动球阀
1 渲染子组件时,外面包裹xxxContext.Provider,通过value属性给后代组件传递数据: <XxxContext.Provider value={数据}>
子组件
</XxxContext.Provider>
123 后代组件读取数据: // 第一种方式:仅适用于类组件
static contextType = xxxContext // 声明接收context
this.context // 读取context中的value数据

// 第二种方式:函数组件与类组件都可以
<xxxContext.Consumer>
{
value => ( //value就是context中的value数据
要显示内容
)
}
</xxxContext.Consumer>
123456789101112

示例
A组件是父组件;B组件是子组件;C组件是孙组件
A组件中初始化了state,里面有一个username属性值为tom;
孙组件C要使用A组件传递过来的username属性。

import React, { Component } from ‘react’
import ‘./index.css’

// 创建一个用于保存数据的上下文
const MyContext = React.createContext()
export default class A extends Component {

state = { username: ‘tom’ }

render() {
return (
<div className=’parent’>
<h3>我是A组件</h3>
<h4>我的用户名是:{this.state.username}</h4>
<MyContext.Provider value={this.state.username}>
<B />
</MyContext.Provider>
</div>
)
}
}

class B extends Component {
render() {
return (
<div className=’child’>
<h3>我是B组件</h3>
<C />
</div>
)
}
}

class C extends Component {
// 声明接收context
static contextType = MyContext
render() {
console.log(this)
return (
<div className=’grand’>
<h3>我是C组件</h3>
<h4>我从A组件接收到的用户名:{this.context}</h4>
</div>
)
}
}
12345678910111213141516171819202122232425262728293031323334353637383940414243444546
若孙组件C为函数式组件FC:
function C() {
return (
<div className=’grand’>
<h3>我是C组件</h3>
<h4>我从A组件接收到的用户名:
<MyContext.Consumer>
{
value => {
return value
}
}
</MyContext.Consumer>
</h4>
</div>
)
}
12345678910111213141516
注意

在应用开发中一般不用context,一般都用它来封装react插件;
比如:react-redux库底层就使用到了context…