Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性
1、语法:
const [xxx, setXxx] = React.useState(initValue)
2、解释:
useState()说明:
参数: 第一次初始化指定的值在内部作缓存
返回值: 包含2个元素的数组, 第1个为内部当前状态值, 第2个为更新状态值的函数 setXxx()2种写法:
2.1、setXxx(newValue): 参数为非函数值, 直接指定新的状态值, 内部用其覆盖原来的状态值
2.2、setXxx(value => newValue): 参数为函数, 接收原本的状态值, 返回新的状态值, 内部用其覆盖原来的状态值
通俗讲就是:定义一个有初始值的变量,在代码中给它赋值来改变它的值
3、使用示例:
①在函数中定义const [aliasText, setAliasText] = useState('');
②在方法逻辑中设置:setAliasText('别名不能为空');
③在需要的地方就可以使用变量aliasText
1、语法:
useEffect(() => {
// 在此可以执行任何带副作用操作
return () => { // 在组件卸载前执行
// 在此做一些收尾工作, 比如清除定时器/取消订阅等
}
}, [stateValue]) // 如果指定的是空数组[], 回调函数只会在第一次render()后执行
2、解释
使用 useEffect 完成副作用操作。赋值给 useEffect 的函数会在组件渲染到屏幕之后执行。相当于
componentDidMount,componentDidUpdate以及componentWillUnmount到一个方法中
如果想执行只运行一次的 effect(仅在组件挂载和卸载时执行),可以传递一个空数组([])作为第二个参数 执行时机
2.1、初始化
2.2、第二个参数值变化时
2.3、卸载(执行第一个参数中的return函数)
3、使用示例
① 调用后台接口的方法
const getVirtualUserKeychain = () => {
const query = {
groupId,
pageSize,
pageNumber
}
//显示加载中的转圈
dispatch({ type: "loading", data: true });
fetchRest('post', '/ListVirtualUserKeychain', query).then((res) => {
//取消显示加载中的转圈
dispatch({ type: "loading", data: false });
if (res.Code === 'SUCCESS') {
dispatch({
type: "refresh",
data: res.Data.pageData,
total: res.Data.total
});
}
})
}
②钩子函数useEffect
useEffect(() => {
getVirtualUserKeychain();
}, [pageSize, pageNumber])
这就是一个列表分页变化就发送请求的例子,初始化会执行getVirtualUserKeychain,当pageSize, pageNumber有变化也会重新请求后端。
1、语法
const [state, dispatch] = useReducer(reducer, init);
2、解释
useState 的替代方案。它接收一个形如 (state, action) => newState 的 reducer,并返回当前的state 以及与其配套的 dispatch 方法。 在某些场景下,useReducer 会比 useState 更适用,例如 state逻辑较复杂且包含多个子值,或者下一个 state 依赖于之前的 state 等。并且,使用 useReducer还能给那些会触发深更新的组件做性能优化,因为你可以向子组件传递 dispatch 而不是回调函数 。
参数:
const中的第一个变量state,就是初始化reduce谁都匹配不上就是返回state,初始等同于useReducer的第二个参数
const中的第二个变量dispatch,是其他地方调用的用来更新变量值的函数
useReducer中的第一个参数reduce,reducer 接受两个参数一个是 state 另一个是 action 。然后返回一个状态
state 和 dispath,state 是返回状态中的值,而 dispatch 是一个可以发布事件来更新 state 的
useReducer中的第二个参数是初始化的state的值
3、使用示例
①钩子函数 useReducer
const [state,dispatch] = useReducer(reduce, {
pageSize: 10,
pageNumber: 1,
totalCount: 0,
list: [],
loading: false
})
②钩子函数中的第一个参数reduce
const reduce = (state, action) => {
switch (action.type) {
case "refresh":
return {
...state,
list: action.data,
totalCount: action.total,
};
case 'change-page-number':
return { ...state, pageNumber: action.pageNumber };
case 'change-page-size':
return { ...state, pageSize: action.pageSize };
case 'loading':
return { ...state, loading: action.data };
default:
return state;
}
};
③在代码逻辑中想要更新某个变量dispatch函数
dispatch({ type: "loading", data: true });
1、语法:
const refContainer = useRef()
2、解释:
Ref Hook可以在函数组件中存储/查找组件内的标签或任意其它数据。useRef返回一个可变的 ref 对象,其 .current属性被初始化为传入的参数(initialValue)。返回的 ref 对象在组件的整个生命周期内持续存在
作用:
保存标签对象,功能与React.createRef()一样
3、 实用示例:
示例1、获取这一行的值
①定义变量const myRef = useRef(null)
②、给标签打上标记
③、获取这个标签中的值alert(myRef.current.value)
示例2、打开模态框
①定义const CreateRef = useRef(null);
②给标签打上标记
③在需要的地方打开模态框
CreateRef.current.openModal();
//很多地方是通过改变visible属性值true和false来显示、关闭模态框的
1、语法:
useImperativeHandle(ref, createHandle, [deps])
2、解释
useImperativeHandle 可以让你在使用 ref 时自定义暴露给父组件的实例值。在大多数情况下,应当避免使用 ref这样的命令式代码。useImperativeHandle 应当与 forwardRef 一起使用。通俗而言就是指定要返给父组件调用的内容
3、示例
function FancyInput(props, ref) {
const inputRef = useRef();
useImperativeHandle(ref, () => ({
focus: () => {
inputRef.current.focus();
}
}));
return <input ref={inputRef} ... />;
}
FancyInput = forwardRef(FancyInput);
渲染 <FancyInput ref={inputRef} /> 的父组件可以调用 inputRef.current.focus()
即暴露给父组件想给的东西,让父组件调用。 例如上面第四条 useRef 中调用了
CreateRef.current.openModal();
在OpenModal函数中的写法:
useImperativeHandle(ref, () => ({
openModal,
}));
const openModal = () => {
setOpen(open);
};
open是父类传过来的 本类函数暴露方式是:
export default forwardRef(OpenModal);