专栏名称: 言sir
web前端
目录
相关文章推荐
庞门正道  ·  写了10年教程,不及雷总说一声。 ·  3 天前  
字体设计  ·  2025新一代设计展主视觉发布 ·  3 天前  
中国食品药品监管杂志  ·  合理用药 | 吃药期间,这种水果最好别碰! ·  2 天前  
51好读  ›  专栏  ›  言sir

react hook用法及实现原理

言sir  · 掘金  ·  · 2019-09-17 03:24

正文

阅读 24

react hook用法及实现原理

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






请到「今天看啥」查看全文