1、hook的简介
Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。
直接贴code,hook实现简版计数器
简单debugger下代码
- 我们可以看到hook是用memorizedState来保存状态
2、useState的简版实现
- 核心作用是给函数组件增加了一个保持状态的功能
let memoizedState; //声明memoizedState
function useState(initialState) {
memoizedState = memoizedState || initialState;
function setState(newState) {
memoizedState = newState; //设置状态时候把新状态赋值给memoizedState
render(); //重新render
}
return [memoizedState,setState]
}
复制代码
从简版的实现来看,还是很容易理解,测试下效果
3、userReducer简介和实现
3.1、userReducer简介
- useState 的替代方案。它接收一个形如 (state, action) => newState 的 reducer,并返回当前的 state 以及与其配套的 dispatch 方法。(如果你熟悉 Redux 的话,就已经知道它如何工作了。)
- 在某些场景下,useReducer 会比 useState 更适用,例如 state 逻辑较复杂且包含多个子值,或者下一个 state 依赖于之前的 state 等。
用userReducer实现计数器,可接收3个参数,reducer | initalArg(初始值) | init (定义初始值的函数)
import React,{Fragment,useReducer} from 'react';
import ReactDOM from 'react-dom';
// reducer,跟redux中reducer一样
const INCREMENT = "INCREMENT";
const DECREMENT = "DECREMENT";
function reducer(state,action){
switch (action.type) {
case INCREMENT:
return {number:state.number+1};
case DECREMENT:
return {number:state.number-1};
default:
return state;
}
}
//初始值
let initalArg = 0;
// 返回初始值的函数
function init(initalArg) {
return {number:initalArg};
}
function Counter() {
// state = {number:0}
const [state,dispatch] = useReducer(reducer,initalArg,init);
return (
<Fragment>
<p>{state.number}</p>
<button onClick={()=>dispatch({type:INCREMENT})}>+</button>
<button onClick={()=>dispatch({type:DECREMENT})}>-</button>
</Fragment>
)
}
function render() {
ReactDOM.render(<Counter />,document.getElementById('root'));
}
render();
复制代码
3.2、简版实现原理
let memoizedState; //声明记忆的状态
function useReducer(reducer,initalArg,init) {
let initialState;
// init如果没有传值,initalArg为默认的初始状态。如果传值,初始值函数处理后作为初始状态
if(typeof init !='undefined'){
initialState = init(initalArg);
}else {
initialState = initalArg;
}
memoizedState = memoizedState || initialState;
function dispatch(action) {
memoizedState = reducer(memoizedState,action);
render();
}
return [memoizedState,dispatch]
}
复制代码
运行结果
3.3、useReducer是useState的内部实现,重写useState实现
let memoizedState;
function useReducer(reducer,initalArg,init) {
let initialState;
if(typeof init !='undefined'){
initialState = init(initalArg);
}else {
initialState = initalArg;
}
memoizedState = memoizedState || initialState;
function dispatch(action) {
memoizedState = reducer(memoizedState,action);
render();
}
return [memoizedState,dispatch]
}
function useState(initialState) {
// 主要是reducer实现,把新状态赋值过去
return