目录
Hooks
三个常用的Hook
State Hook
Effect Hook
Ref Hook
Context
Router 6
声明式路由
编程式路由导航
Hooks
(1) Hook是react 18.8.0版本新增的特性/语法
(2) 可以让我们在函数式组件中使用state以及其他的react特性
三个常用的Hook
(1) State Hook: React.useState()
(2) Effect Hook: React.useEffect()
(3) Ref Hook: React.useRef()
State Hook
(1) State Hook 让函数组件也可以有state状态 并进行状态数据的读写操作
(2) 语法: const[变量名,set修改变量的方法] = React.useState(initvalue)
(3) useState()说明:
参数: 第一次初始化指定的值在内部作缓存
返回值: 包含两个元素的数组 第一个为内部当前状态的值 第二个为更新状态值的函数方法
(4) setXXX()2种写法:
setXXx(newValue) : 参数为非函数值 直接指定新的状态值 内部用其覆盖原来的状态值
setXXx(value=> newValue) : 参数为函数 接收原来的状态值 返回新的状态值 内部用其覆盖原来的状态值
先使用传统的类式组件来进行数据处理然后进行比对
类式组件:
函数式组件:
测试
Effect Hook
(1) Effect Hook 可以让你在函数组件中执行副作用操作(用于模拟类组件中的生命周期钩子)
(2) React中的副作用操作:
发ajax请求数据操作
设置订阅 /启动定时器
手动更改真实Dom
(3) 语法和说明:
useEffect(()=>{
//执行副作用操作
return ()=>{
//在组件卸载前执行
// 在此做一些收尾工作 比如清除定时器 /取消订阅等
}
},[stateValue] //如果指定的是[],回调函数只会在第一次render()后执行)
(4) 可以把useEffect Hook 看做如下三个函数的组合:
componentDidMount() 组件要挂载时执行
componentDidUpdate() 组件更改时执行
componentWillUnmount() 组件要卸载前执行
类式组件写法:
测试
函数式写法:
测试:
Ref Hook
使得函数式组件也可以像类式组件一样使用ref
类式组件:
测试
函数式:
测试
Context
一种组件间通信方式 常用于[祖父组件] 与[后代组件]间通信
使用:
(1) 创建 Context容器对象
const xxxContext = React.createContext()
(2) 渲染子组件时 外面包裹 xxxContext.Provider 通过value属性给后代组件传递数据
<xxxContext.Provider value={数据}>
子组件
</xxxContext.Provider>
(3) 后代组件读取数据:
第一种方式: 仅适用类组件方式:
static contextType = xxxContext //声明接收 context
this.context //读取context中的value数据
//第二种方式: 函数组件类组件都适用
<xxxContext.Consumer>
{
value=>(//value就是context中的value数据)
要显示的内容
}
</xxxContext.Consumer>
先看下使用props传递方式.父->子->孙
可以看到,如果想把父组件App的名字传递给孙组件Cpp,如果使用props的话需要一层一层进行props传递,而且在每一层还需要再次声明接收,这样很不方便
如果使用context可以直接将数据由父->子
函数式写法:
Router 6
React Router以三个不同的包发布到npm上 分别为:
(1) react-router:路由的核心库 提供了很多的组件和钩子
(2) react-router-dom:包含react-routerd所有的内容 并添加一些专门用于Dom的组件 例如:<BrowerRouter>
(3) react-router-native:包括了react-router所有内容 并添加一些专门用于Reactnative的api 例如:<NativeRouter>
与router5版本相比 主要变化:
(1) 内置组件的变化:移除<Switch/> 新增<Routers/>等
(2) 语法的变化: component={组件名} 变为 element={<组件名/>}
(3) 新增多个hook: userParams,useNavigate,useMatch等
(4) 官方明确推荐使用函数式组件
声明式路由
代码示例:
首先安装最新6路由
npm i react-router-dom
定义两个子组件
再封装一个包裹组件容器
测试
如果有许多页面组件需要路由配置时,可以直接将路由组件的配置进行提取成单个路由表文件进行解耦
还可以进一步提取,将配置的路由表单独提取为一个文件
引入router表文件
效果和之前写法一样
嵌套路由并传参
shop父组件,嵌套Message和news组件,Message组件再嵌套Detail组件,message组件传参到detail组件进行显示测试
params传参:
定义路由规则:
detail进行接参时有两种方式,可以直接进行userParams解构,也可以使用useMatch进行解析,两者稍有区别
测试
可以看到参数的话可以直接从useParams中进行解析,而如果使用useMatch的话还需要进行路径和参数占位,并且取出的数据并不可以直接解构取数
所以一般情况下还是useParams中使用较多
search传参:
search传参不需要在路由文件中路径上进行参数占位 传参时可以直接进行拼接传参
传参
接参
测试
可以看到useSearchParams和useLocation都可以取到参数,区别就是useSearchParams解构得到的是map类型的参数和更改参数的方法,useLocation得到的是参数拼接的字符串,如果想要使用参数还需要进一步的解析字符串
state传参
state传参和search传参一样在路由路径中不需要再配置参数占位,所以路由路径不用动
从useLocation()的state属性中进行参数的解析
测试
编程式路由导航
router6中提供useNavigate()接口来优化router5的编程式导航
注意:编程式导航传参只能传递state形式的参数,search和params形式参数直接拼在路径上即可
测试
控制页面前进后退
之前router5版本中如果想让一般组件也有路由组件的history的话是需要使用withOutr标签的,6版本的路由不需要这么麻烦,也是直接使用useNavigate就可以解决
先建一个一般组件
测试