1.使用Hook状态管理
Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。
前言
我们大部分 React 类组件可以保存状态,而函数组件不能? 并且类组件具有生命周期,而函数组件却不能?
React 早期版本,类组件可以通过继承PureComponent来优化一些不必要的渲染,相对于函数组件,React 官网没有提供对应的方法来缓存函数组件以减少一些不必要的渲染,直接 16.6 出来的 React.memo函数。
React 16.8 新出来的Hook可以让React 函数组件具有状态,并提供类似 componentDidMount和componentDidUpdate等生命周期方法。
提示:本篇文章仅是我个人理解,如有我理解错误的地方,欢迎您指教我的问题
一、Hooks是什么?
Hooks是状态管理的一种,比如其他的还有Mobx,Redux这些常用的状态管理器。不同的是Hooks是针对于Function来做监听状态的,由于Function是无状态组件,Hooks的作用就是赋予状态给Function组件,使他实现和Class差不多的效果。
二、使用步骤
1.引入库
代码如下(示例):
import React, {
useState,
useCallback,
useEffect,
useRef,
useContext,
useReducer,
useMemo,
} from 'react';
2.读入数据
代码如下(示例):
//usestate设置初始化值
import React, { useState } from 'react';
const [count, setCount] = useState(0);
--------------------------------------------------
//useEffect:类似于saga,副作用,一般用于网络请求
import React, { useEffect } from 'react';
useEffect(() => {
console.log('componentDidMount');//网络请求等...
return () => {
console.log('componentWillUnmount ');//卸载定时器等...
};
}, []);//设置刷新限制
//使用useEffect实现网络请求
// 页面进来只调用一次
useEffect(()=>{
axios.get('/getYearMonth').then(res=> {
console.log('getYearMonth',res);
setValues(oldValues => ({
...oldValues,
fileList:res.data.msg
}));
})
},[]);
--------------------------------------------------
//content 父子组件传值
import React, { useState } from 'react';
function Show({ count, age, clear }) {
return (
<div>
数量:{count}
年龄:{age}
<button
type="button"
onClick={() => { clear(); }}
>
复原
</button>
</div>
);
}
function HooksContext() {
const [count, setCnt] = useState(0);
const [age, setAge] = useState(16);
function clear() {
setCnt(0);
setAge(16);
}
return (
<div>
<p>小女子芳年{age}</p>
<p>你点击了{count}次</p>
<button
type="button"
onClick={() => { setCnt(count + 1);
setAge(age + 1); }}
>
点击+1
</button>
<Show count={count} age={age} clear={clear} />
</div>
);
}
//通过给Show组件属性赋值,然后在Show函数组件中以解构参数的方式获取父组件的值。这种传值方式和类组件本质上还是一样的。
--------------------------------------------------
//useContext读取 context 的值以及订阅 context 的变化
//content提供了一种树状结构,被Context.Provider所包裹的所有组件,都可以直接取数据。
import { createContext } from 'react';
HooksContext(()=> {
return (
//创建 <MyContext.Provider> 来为下层组件提供 context
<ShowContext.Provider value={{ count, age, clear }}>
);
})
HooksContexts(()=>{
//从ShowContext中取值
const { count, age, clear } = useContext(ShowContext);
return (
.............
);
})
--------------------------------------------------
//userReducer 是 useState的替代方案
import React, { userReducer } from 'react';
countReducer((state, action)=> {//实现逻辑
switch (action.type) {
case 'add':
return state + 1;
case 'minus':
return state - 1;
default:
return state;
}
})
HooksEffect(()=> {//引用实现
const [count, dispatch] = useReducer(countReducer, 0);
return (
<div>
<p>你点击了{count}次</p>
<button
type="button"
onClick={() => { dispatch({ type: 'add' }); }}
>
点击+1
</button>
<button
type="button"
onClick={() => { dispatch({ type: 'minus' }); }}
>
点击-1
</button>
</div>
);
})
--------------------------------------------------
//useMemo 设置依赖项数组,只有当依赖项数组发生改变才会执行参数函数
import React, { useMemo } from 'react';
const myAge = useMemo(() => ageChange(age), [age]);//shouldComponentDidUpdata
//和这个生命周期还有些许不同。它是当检测的state发生变化时而执行某些函数,避免额外的开销,节省性能。
--------------------------------------------------
//useRef 获取组件实例对象或者DOM对象,映射,浅拷贝,‘.current’,监听dom某个节点
import React, { useRef } from 'react';
HooksUseRef(()=>{
const [inputValue, setInputValue] = useState();
const inputRef = useRef(null);
function inputChangeHandle(e) {
setInputValue(e.target.value);
}
inputRefChangeHandle(()=> {
console.log(inputRef.current.value);
}
return (
<input
ref={inputRef}
onChange={inputRefChangeHandle}
type="text"
/>
));
})
--------------------------------------------------
//useCallBack 是用来缓存函数的
//useCallBack和useMemo的不同点在于useMemo相当于缓存state,而useCallBack相当于缓存函数
//官方给的解释是这样的useCallback(fn, deps) 相当于 useMemo(() => fn, deps)。
//使用useCallback如果没有依赖,则只会执行一次,只有依赖改变,
//才会返回新的函数可以根据这个规则实现bind的效果。
import React, { useCallBack} from 'react';
--------------------------------------------------
//useHooks 自定义函数 需要在函数前面加上use关键词 后面应该用大写字母与use分隔开-------use Hooks
HooksFunction(()=> {
return (
.......................
);
})
以上则是Hooks的API部分案例
总结
useState:设置初始化值;userEffect:类似于saga,副作用,一般用于网络请求
useMemo:设置依赖项数组,只有当依赖项数组发生改变才会执行参数函数,解决重复渲染,解决性能优化
useRef:获取组件实例对象或者DOM对象,映射,浅拷贝,‘.current’,监听dom某个节点
forwardref:用于父子组件传值,传递引用,参数是{props,res}
useContext:让你能够读取 context 的值以及订阅 context 的变化,需要在上层组件树中使用 <MyContext.Provider> 来为下层组件提供 context并且在组件外部创建一个公用creteContext,组件之间共享状态
useReducer:类似于redux-reducer,用于处理复杂的state逻辑并且包含多个子值,是usestate的替换方案,使用useReduser还会给触发深更新组件做性能优化浅渲染
useHook:自定义hook,需要在函数前面加上use关键词
useCallback:用来缓存函数的
注意事项:
(1)hooks的state状态挂钩是按照顺序过来的
(2)hooks不可以再类中使用,只可以在函数中。
(3)hooks不可以在条件语句中使用这样会导致hook的调用顺序发生改变
(4)要想有条件的执行effect,可以直接放到hook里面
(5)如果有需要两个函数需要重用状态逻辑,则自定义hook,唯一要求是函数要以use开头
(6)React:16.8.0 ;React-native:0.59