React HOOK:useReducer

useReducer

1.useReducer用最简单的话来说就是允许我们在函数组件里面像使用redux一样通过reducer和action来管理我们组件状态的变换

语法:

const [state, dispatch] = useReducer(reducer, initialArg, init?)
                                     
//useReducer和useState类似,都是用来管理组件状态的,只不过和useState的useReducer不一样的是,useReducer返回的dispatch函数是用来触发某些改变state的action而不是直接设置state的值,至于不同的action如何产生新的state的值则在reducer里面定义。
//useReducer接收的三个参数分别是:
                                     
//reducer: 这是一个函数,它的签名是(currentState, action) => newState,从它的函数签名可以看出它会接收当前的state和当前dispatch的action为参数,然后返回下一个state,也就是说它负责状态转换的工作。
                                     
//initialArg:如果调用者没有提供第三个init参数,这个参数代表的是这个reducer的初始状态,如果init参数有被指定的话,initialArg会被作为参数传进init函数来生成初始状态。
                                     
//init: 这是一个用来生成初始状态的函数,它的函数签名是(initialArg) => initialState,从它的函数签名可以看出它会接收useReducer的第二个参数initialArg作为参数,并生成一个初始状态initialState

 

 

案例:

import React, { useState, useReducer } from 'react'
​
let todoId = 1
​
const reducer = (currentState, action) => {
  switch(action.type) {
    case 'add':
      return [...currentState, {id: todoId++, text: action.text}]
    case 'delete':
      return currentState.filter(({ id }) => action.id !== id)
    default:
      throw new Error('Unsupported action type')
  }
}
​
const Todo = ({ id, text, onDelete }) => {
  return (
    <div>
      {text}
      <button
        onClick={() => onDelete(id)}
      >
        remove
      </button>
    </div>
  )
}
​
const App = () => {
  const [todos, dispatch] = useReducer(reducer, [])
  const [text, setText] = useState('')
​
  return (
    <>
      {
        todos.map(({ id, text }) => {
          return (
            <Todo
              text={text}
              key={id}
              id={id}
              onDelete={id => {
                dispatch({ type: 'delete', id })
              }}
            />
          )
        })
      }
      <input onChange={event => setText(event.target.value)} />
      <button
        onClick={() => {
          dispatch({ type: 'add', text })
          setText('')
        }}
      >
        add todo
      </button>
    </>
  )
}
​
ReactDOM.render(<App />, document.getElementById('root'))
​

 

2.useReducer +useContext实现redux

import React from "react"
let context1=React.createContext(null)
export default context1
import { useRef, useEffect, useCallback, useState, useMemo, useReducer } from 'react'
import Mycontext from "./MyContext.jsx"
import Mybox2 from "./Mybox2.jsx"
function Mybox() {
    let [state,dispach]=useReducer((state,action)=>{
        
        if(action.type=="msg"){
          
            state.msg= action.value
        }
        else if(action.type=="age"){
            state.age= action.value
        }
        console.log(state)
        return JSON.parse(JSON.stringify(state))
       
    },{msg:"hello",age:18})
   
    // useReducer+useContext ==>做出redux框架的功能(全局数据共享)
    //1.给根组件生成一个数据容器(不是用useState生成的,是用useReducer)
    //2.把这个数据容器(是一个hook容器)传给子代组件使用,使用的技术是useContext
    return (
        <Mycontext.Provider value={[state,dispach]}>
            <h1>1</h1>
            <p>{state.msg}</p>
            <Mybox2></Mybox2>
        </Mycontext.Provider>
    )
}
​
export default Mybox
import {useReducer,useContext} from 'react'
import context1 from "./MyContext.jsx"
import MyBox3 from "./MyBox3.jsx"
export default function Mybox2() {
  const [state,dispacth] = useContext(context1)
  console.log(state);
  let fn=()=>{
      console.log(6666)
    dispacth({type:"msg",value:"1234567"})
  }
    return (
        <div>
            <h1>2</h1>
            <p>{state.msg}</p>
            <button onClick={fn}>修改</button>
            <MyBox3></MyBox3>
</div>
    )
}
​
 

import React,{useContext} from 'react'
import context2 from "./MyContext.jsx"
​
export default function Mybox3() {
    let [state,dispacth]=useContext(context2)
    return (
        <div>
            <h1>3</h1>
            <p>{state.msg}</p>
            
        </div>
    )
}
​

 

 
posted on 2022-10-19 16:09  香香鲲  阅读(62)  评论(0编辑  收藏  举报