欢迎来到我的博客
📔博主是一名大学在读本科生,主要学习方向是前端。
🍭目前已经更新了【Vue】、【React–从基础到实战】、【TypeScript】等等系列专栏
🛠目前正在学习的是🔥 R e a c t 框架 React框架 React框架🔥,中间穿插了一些基础知识的回顾
🌈博客主页👉codeMak1r.小新的博客
本文被专栏【React–从基础到实战】收录
🕹坚持创作✏️,一起学习📖,码出未来👨🏻💻!
(1). setState(stateChange, [callback]) -----对象式的setState
this.setState({ count: count + 1 }, () => { // render调用后 console.log(this.state.count) });
- 1
- 2
- 3
- 4
- stateChange为状态改变对象,该对象可以体现出状态的更改;
- callback是可选的回调函数,它在状态更新完毕,页面也更新后(render调用后)才被调用
(2). setState(updater, [callback]) ----- 函数式的setState
this.setState((state, props) => { console.log(state, props) return { count: state.count + 1 } });
- 1
- 2
- 3
- 4
- updater为返回stateChange对象的函数;
- updater可以接收到state和props;
- callback是可选的回调函数,它在状态更新、页面也更新后(render调用后)才被调用
总结:
对象式的setState是函数式的setState的简写方式(语法糖)
使用原则:
(1)如果新状态不依赖于原状态 ==== 使用对象方式
(2)如果新状态依赖于原状态 ==== 使用函数方式
(3)如果需要在setState()执行后获取最新的状态数据,要在第二个callback函数中读取
React状态的更新是异步的!!
引入lazy函数和Suspense组件
import React, { Component, lazy, Suspense } from 'react'
实现路由懒加载
// 1.通过React的lazy函数配合import()函数动态加载路由组件 ===> 路由组件代码会被分开打包
const Login = lazy(() => import('@/pages/Login'))
// 2. 通过指定在加载得到路由打包文件前显示一个自定义loading界面
<Suspense fallback={<h1>loading</h1>}>
<Switch>
<Route path="/xxx" component={xxx}/>
<Redirect to="/login"/>
</Switch>
</Suspense>
// 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" />
</>
)
}
可以不用必须有一个真实的DOM根标签了
一种组件间通信方式,常用于【祖组件】与【后代组件】间通信
创建Context容器对象:
const Xxxcontext = React.createContext()
- 1
渲染子组件时,外面包裹xxxContext.Provider,通过value属性给后代组件传递数据:
<XxxContext.Provider value={数据}> 子组件 </XxxContext.Provider>
- 1
- 2
- 3
后代组件读取数据:
// 第一种方式:仅适用于类组件 static contextType = xxxContext // 声明接收context this.context // 读取context中的value数据 // 第二种方式:函数组件与类组件都可以 <xxxContext.Consumer> { value => ( //value就是context中的value数据 要显示内容 ) } </xxxContext.Consumer>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
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>
)
}
}
若孙组件C为函数式组件FC:
function C() {
return (
<div className='grand'>
<h3>我是C组件</h3>
<h4>我从A组件接收到的用户名:
<MyContext.Consumer>
{
value => {
return value
}
}
</MyContext.Consumer>
</h4>
</div>
)
}
在应用开发中一般不用context,一般都用它来封装react插件;
比如:react-redux库底层就使用到了context…