手写 Redux

从零开始手写redux

全局state的读写

例1.使用Context读写appState

import React, {
    useState, useContext } from "react"
import ReactDOM from 'react-dom'
import './style.css'

const appContext = React.createContext(null)
const App = () => {
   
  const [appState, setAppState] = useState({
   
    user: {
    name: 'frank', age: 18 }
  })
  const contextValue = {
    appState, setAppState } //封装成一个对象,塞给上下文
  return (
    <appContext.Provider value={
   contextValue}>
      <大儿子 />
      <二儿子 />
      <小儿子 />
    </appContext.Provider >
  )
}
const 大儿子 = () => <section>大儿子<User /></section>
const 二儿子 = () => <section>二儿子<UserModifier /></section>
const 小儿子 = () => <section>小儿子</section>

const User = () => {
    //获取信息
  const contextValue = useContext(appContext)
  return <div> User:{
   contextValue.appState.user.name} </div>
}
const UserModifier = () => {
    //修改信息
  const {
    appState, setAppState } = useContext(appContext);
  const onChange = (e) => {
   
    appState.user.name = e.target.value
    setAppState({
    ...appState })
  }
  return <div>
    <input value={
   appState.user.name} onChange={
   onChange} />
  </div>
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

在这里插入图片描述

1.setState特点
如果你给的对象是原来那个对象的引用,只要是引用相同,那我直接不变,setState时是不会生效的。
解决方法: 创建一个新的对象,新的对象包含了appState的所有属性

const contextValue = {
    appState, setAppState } 

const UserModifier = () => {
    //修改
  const contextValue = useContext(appContext);
  onChange(e){
   
    contextValue.appState.user.name = e.target.value
      contextValue.setAppState({
   ...contextValue.appState})
   // contextValue.setAppState(contextValue.appState) 错误
  } 
  ... 
}

reducer的来历

reducer是如何规范state的创建流程的。

目前创建的state特别不规范,它直接修改了原始的state,
我们应该提供一个函数来帮它创建新的state。

const reducer = (state, actionType, actionData) => {
   
//const createNewState = (state, actionType, actionData) => {
   
  if (actionType === 'updateUser') {
   
    return {
      //新的对象
      ...state,//首先会拷贝user之外的属性
      user: {
     //创建user
        ...state.user,
        ...actionData 
      }
    }
  } else {
   
    return state
  }
}
const UserModifier = () => {
   
  const {
    appState, setAppState } = useContext(appContext);
  const onChange = (e) => {
   
    setAppState(createNewState(appState, 'updateUser', 
      {
   name: e.target.value}))
  //setAppState(reducer(appState, 'updateUser', {name: e.target.value}))    
  }
  return <div>
    <input value={
   appState.user.name} onChange={
   onChange} />
  </div>
}

return的是全新的对象,规范了创建state的过程。
现在把函数名createNewState改为reducer,这就是reducer的由来。

不同的是reducer只接受2个参数:将actionType, actionData统一成一个叫action的东西,它接受一个type和payload{type,payload},payload比较麻烦,其实就是data的意思。

const reducer = (state, {
     type, payload }) => {
   
  if (type === 'updateUser') {
   
    return {
   
      ...state,
      user: {
   
        ...state.user,
        ...payload
      }
    }
  } else {
   
    return state
  }
}
const UserModifier = () => {
   
  const {
    appState, setAppState } = useContext(appContext);
  const onChange = (e) => {
    
    setAppState(reducer(appState, {
    type: 'updateUser',
      payload: {
    name: e.target.value } }))
  }
  return <div>
    <input value={
   appState.user.name} onChange={
   onChange} />
  </div>
}

reducer就是用来规范state创建流程的一个函数。

dispatch的来历

如何使用dispatch来规范setState的流程。

先看下我们是如何setState的:
当我们改name、age、group时,每次都要写前面3个单词,既然每次setState都要复制这3份,不如干脆写一个函数 dispatch

setAppState(reducer(appState, {
    type: 'updateUser', 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老老老老李

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值