03|实现 useReducer 和 useState

使用 useReducer

在此之前,需要在demo/which-react.js中将useReducer从react中引入,并将ReactDOM更换为从react-dom引入

import { Component, Fragment, useReducer } from 'react';
import ReactDOM from 'react-dom/client';

// import { Component, Fragment } from '../src/react';
// import ReactDOM from '../src/react-dom';

export {Component,Fragment,useReducer,ReactDOM
} 

demo/src/main.jsx中的 FunctionComponent 中添加useReducer

function FunctionComponent(props) {const [state, dispatch] = useReducer(x => x + 1, 0)return (<div className='function'><p>{props.name}</p><div>{state}</div><button onClick={dispatch} >+1</button></div>)
} 

那么每次点击button都会将state + 1,有了我们想要的效果,接下来我们去实现它

实现 useReducer

将 React 的引入重新设定为自己写的(修改which-react.js),创建src/ReactFiberHooks.ts

export function useReducer(reducer, initalState) {const dispatch = () => {console.log('useReducer dispatch log')}// 暂时直接返回return [initalState, dispatch]
} 

接着会发现点击 button 没有触发 dispatch 里的 console,这是因为我们还没有实现 React 事件,暂时只是将事件作为属性挂在dom上

// src/utils.ts
export function updateNode(node, nextVal) {Object.keys(nextVal).forEach(key => {if (key === 'children') {if (isStringOrNumber(nextVal[key])) {node.textContent = nextVal[key]}} else {node[key] = nextVal[key] // 这里直接当作属性放到 dom 上了}})
} 

这里我们先简单处理一下,能让事件能响应(注意这里并不是真正的 React 事件实现方式)

export function updateNode(node: HTMLElement, nextVal) {Object.keys(nextVal).forEach(key => {if (key === 'children') {if (isStringOrNumber(nextVal[key])) {node.textContent = nextVal[key]}} else if (key.slice(0, 2) === 'on') {// 简单处理一下事件响应(并不是真正的React 事件)const eventName = key.slice(2).toLocaleLowerCase()node.addEventListener(eventName, nextVal[key])} else {node[key] = nextVal[key]}})
} 

点击按钮能让console.log('useReducer dispatch log')执行出来了

实现 mount 时的 useReducer

import { Fiber } from "./ReactFiber"

interface Hook {memoizedState: any, // statenext: null | Hook // 下
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值