react hooks 之 useReducer

2021-12-02  本文已影响0人  RickyWu585

注意:useReducer改变state,是会更新页面的


image.png
1. 创建初始值
const initial = {
  n: 0
}
2. 创建所有操作
const reducer = (state, action) => {
  if (action.type === 'add') {
    return {n: state.n + action.number}
  } else if (action.type === 'multi') {
    return {n: state.n * 2}
  } else {
    throw new Error('unknown type')
  }
}
3. 传给useReducer
const App = props => {
  const [state, dispatch] = useReducer(reducer, initial)
  const onClick = ()=>{
    dispatch({type:'add',number:1})
  }
  const onClick2 = ()=>{
    dispatch({type:'add',number:2})
  }
  return (
    <div>
      <h1>{state.n}</h1>
      <button onClick={onClick}>+1</button>
      <button onClick={onClick2}>+2</button>
    </div>
  )
}
import React, {useState, useContext, useReducer, createContext, useEffect} from 'react'

const store = {
  user: null,
  books: null,
  movies: null
}

const obj = {
  'setUser': (state, action) => {
    return {...state, user: action.user}
  },
  'setBooks': (state, action) => {
    return {...state, books: action.books}
  },
  'setMovies': (state, action) => {
    return {...state, movies: action.movies}
  }
}
// 牛比
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()
  }*/
  const fn = obj[action.type]
  if (fn) {
    // fn执行得到的是一个对象,因此加 return 的意思是要把这个对象返回出去。
    // 不加的话是仅仅得到,不会在这个函数里返回的
    return fn(state, action)
  } else {
    throw new Error('unknown type')
  }
}

const Context = createContext(null)

const App = () => {
  const [state, dispatch] = useReducer(reducer, store)
  return (
    <Context.Provider value={{state, dispatch}}>
      <User/>
      <hr/>
      <Books/>
      <Movies/>
    </Context.Provider>
  )
}

const User = () => {
  const {state, dispatch} = useContext(Context)
  useEffect(() => {
    console.log('state');
    console.log(state);
    ajax('/user').then(res => {
      console.log('res');
      console.log(res);
      dispatch({
        type: 'setUser',
        user: res.name
      })
    })
  }, [])

  return (
    <div>
      <h1>个人信息</h1>
      <div>
        name:{state.user ? state.user : ''}
      </div>
    </div>
  )
}
const Books = () => {
  return (
    <div>
      <h1>我的书籍</h1>
    </div>
  )
}
const Movies = () => {
  return (
    <div>
      <h1>我的电影</h1>
    </div>
  )
}

function ajax(path) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (path === "/user") {
        resolve({
          id: 1,
          name: "Frank"
        });
      } else if (path === "/books") {
        resolve([
          {
            id: 1,
            name: "JavaScript 高级程序设计"
          },
          {
            id: 2,
            name: "JavaScript 精粹"
          }
        ]);
      } else if (path === "/movies") {
        resolve([
          {
            id: 1,
            name: "爱在黎明破晓前"
          },
          {
            id: 2,
            name: "恋恋笔记本"
          }
        ]);
      }
    }, 1000);
  });
}

export default App

上一篇下一篇

猜你喜欢

热点阅读