React的Hooks2——useReducer

本文深入讲解了React Hooks中的useReducer钩子,通过实例演示了如何使用useReducer来管理组件的状态,包括初始化状态、定义状态更新逻辑及替代Redux的实现方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

React的Hooks2——useReducer

是用来规范创建state的创建流程的。

文档中其实是这么说的:是useState 的替代方案。它接收一个形如 (state, action) => newState 的 reducer,并返回当前的 state 以及与其配套的 dispatch 方法。

代码要分四步走:

1. 创建初始值initialState
2. 创建所有操作reducer(state,action)
3. 传给useReducer,得到读和写API
4. 调用写({type:"操作类型"})
const initial = {
  n:0
}
const reducer = (state,action)=>{
  if(action.type==='add'){
    return {n:state.n+action.number}
  }else if(action.type==="mult"){
    return {n:state.n*action.number}
  }else{
    throw new Error('unknown type')
  }
}
function App(){
  const [state, dispatch] = useReducer(reducer, initial)
  const {n} = state
  const onClick=()=>{
    dispatch({type:'add',number:1})
  }
  const onClick2=()=>{
    dispatch({type:'mult',number:2})
  }
  return(
    <div className="App">
      <h1>n:{n}</h1>
      <button onClick={onClick}>+1</button>
      <button onClick={onClick2}>*2</button>
    </div>
  )
}

useReducer代替Redux:
步骤:
1. 将数据几集中在一个store对象
2. 将所有操作集中在reducer
3. 创建一个Context
4. 创建对数据的读写API
5. 将第四步的内容放到第三步的Context
6. 用Context.Provider将Context提供给所有组件
7. 各个组件用useContext获取读写API

import React, { createContext,useReducer,useContext,useEffect } from 'react';
import ReactDOM from 'react-dom';




//1. 将数据几种在一个store对象
const store = {
  user: null,
  books: null,
  movies: null
}
//2.将所有操作集中在reducer
const reducer = (state,action) => {
  switch(action.type){
    case 'setUser':
      return {...state,user:action.user}
    case 'setBooks':
      return {...state,books:action.books}
    case 'setMovies':
      return {...state,movies:action.movies}
    default:
      throw new Error()
  }
}
//3. 创建一个Context
const Context = createContext(null)
function App(){
  //4. 创建对数据的读写API
  const [state, dispatch] = useReducer(reducer, store)
  return(
    // 第一个花括号表示里面的是JS内容,里面的花括号代表是对象,只是使用ES6的语法缩写了
    //5. 将第四步的内容放到第三步的Context 6. 用Context.Provider将Context提供给所有组件
    <Context.Provider value = {{state,dispatch}}>
      <div>
        <User />
        <hr />
        <Books />
        <Movies />
      </div>
    </Context.Provider>
  )
}

function User(){
  //7. 各个组件用useContext获取读写API
  const {state,dispatch} = useContext(Context)
  //useEffe第二个参数是空[]时,表示只会渲染一次
  useEffect(() => {
    ajax("/user").then(user=>{
      dispatch({type:"setUser",user:user})
    })
  }, [])
  
  return(
    <div>
      <h1>个人信息</h1>
      <div>name:{state.user?state.user.name:""}</div>
    </div>
  )
}


function Books(){
  const {state,dispatch} = useContext(Context)
  useEffect(() => {
    ajax("/books").then(books=>{
      dispatch({type:"setBooks",books:books})
    })
  }, [])
  return(
    <div>
      <h1>我的书籍</h1>
      <ol>
        {state.books?state.books.map(book=><li key={book.id}>{book.name}</li>):"加载中"}
      </ol>
    </div>
  )
}


function Movies(){
  const {state,dispatch} = useContext(Context)
  useEffect(() => {
    ajax("/movies").then(movies=>{
      dispatch({type:"setMovies",movies:movies})
    })
  }, [])
  return(
    <div>
      <h1>我的电影</h1>
      <ol>
        {state.movies?state.movies.map(movie=><li key={movie.id}>{movie.name}</li>):"加载中"}
      </ol>
    </div>
  )
}






const rootElement = document.getElementById('root')
ReactDOM.render(<App />,rootElement)


function ajax(path){
  return new Promise((resolve,reject)=>{
    setTimeout(()=>{
      if(path==="/user"){
        resolve({
          id:1,
          name:"lu"
        })
      }else if(path==="/books"){
        resolve([
        {
          id:1,
          name:"JavaScript高级程序设计"
        },
        {
          id:2,
          name:"JavaScript精粹"
        }
      ])
      }else if(path==="/movies"){
        resolve([
          {
            id:1,
            name:"送你一朵小红花"
          },
          {
            id:2,
            name:"美人鱼"
          }
        ])
      }
    },2000)
  })
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值