useReducer代替Redux

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)
  })
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值