Reac-redux的基本使用

import React, { Component, useState, useEffect } from 'react'
import { useControl } from './hooks/useControl'
import ReactDOM from 'react-dom/client'
import { nanoid } from 'nanoid'
import {
  // 🤴🏻🟨 推荐使用as将路由重命名为Router
  HashRouter,
  BrowserRouter as Router,
  Route,
  Link,
  NavLink,
  Switch,
  Redirect,
} from 'react-router-dom'

import { legacy_createStore as createStore } from 'redux'
import store from './store'

const root = ReactDOM.createRoot(document.getElementById('root'))

/**
 * 学习目标:🍅使用redux创建store数据仓库
 * 步骤:
 *  1. 下包/导入 createStore
 *  2. 调用函数createStore(reducer函数)
 *  语法:
 *  1. 创建store:createStore(function (state = 初始值) {return state})
 *  2. 获取state:store.getState()
 */
const initState = {
  count: 0,
  msg: 'Hello!',
}

// 🍅【创建store && 获取store中的数据】
function AppCom01() {
  // reducer函数的形参, 用来设置state的初始值
  const store = createStore(function (state = initState) {
    // 💥 reducer函数一定要有返回值
    return state
  })
  const reduxState = store.getState()
  console.warn('reduxState: ', reduxState)
  const { count, msg } = reduxState
  return (
    <>
      <div>
        <p>count: {count}</p>
        <p>msg: {msg}</p>
      </div>
    </>
  )
}

// 🍅【使用dispatch修改state数据】
function AppCom02() {
  // reducer通过第二个参数,接收action对象
  const store = createStore(function (state = { count: 0 }, action) {
    // reducer函数通过返回值,修改state
    // 💥不可变数据:新值覆盖旧值
    if (action.type === 'add') {
      return { ...state, count: state.count + 1 }
    }
    if (action.type === 'des') {
      return { ...state, count: state.count - 1 }
    }
    return state
  })

  console.log('store.getState() ===> Before: ', store.getState()) // {count: 0}

  // 1. 🛑 dispatch(action对象)
  // action对象必须存在一个type字段
  store.dispatch({ type: 'add' }) // 1
  store.dispatch({ type: 'add' }) // 2
  store.dispatch({ type: 'des' }) // 1
  console.log('store.getState() ===> After: ', store.getState())
}

// 🍅【使用subscribe监听store数据的变化】
// 语法: const 解除监听的函数 = store.subscribe(() => { // 可以获取到更新后的值})
function AppCom03() {
  const store = createStore((state = { count: 0 }, action) => {
    if ('add' === action.type) {
      return { ...state, count: state.count + 1 }
    }
    if ('des' === action.type) {
      return {
        ...state,
        count: state.count + 1,
      }
    }
    return state
  })

  store.dispatch({ type: 'add' })
  store.dispatch({ type: 'add' })

  // 💥 subscribe需要在dispatch触发之前开启监听
  const unFn = store.subscribe(() => {
    console.log(store.getState(), 'getState')
  })

  store.dispatch({ type: 'add' })
  store.dispatch({ type: 'add' })
  store.dispatch({ type: 'des' })
  // unFn是取消监听的函数
  unFn()
  store.dispatch({ type: 'des' })
}

// 🍀- 推荐写法 - 🟨 创建store
function AppCom04() {
  // 使用单独的常量,维护state的初始值
  const initState = {
    count: 0,
    msg: ' we are the world!',
    list: [],
  }

  // 推荐使用单独的函数,定义reducer函数
  function countReducer(state = initState, { type }) {
    // 使用switch语句,替代if语句
    switch (type) {
      case 'add':
        return { ...state, count: state.count + 1 }
      case 'des':
        return { ...state, count: state.count - 1 }
      default:
        return state
    }
  }

  const store = createStore(countReducer)

  store.dispatch({ type: 'add' })
  store.dispatch({ type: 'add' })

  const unFn = store.subscribe(() => {
    console.log(store.getState(), 'getState')
  })

  store.dispatch({ type: 'add' })
  store.dispatch({ type: 'add' })
  store.dispatch({ type: 'des' })
  unFn()
  store.dispatch({ type: 'des' })
}

// 🧿 Redux - 在React中基本使用
function AppCom05() {
  const [show, setShow] = useState(true)
  return (
    <>
      <div>
        <h1>Redux基础使用案例</h1>
        <button onClick={() => setShow(!show)}>点击切换卸载挂载</button>
        {show && <Son />}
      </div>
    </>
  )
}

function Son() {
  // 从redux中获取初始值
  const [count, setCount] = useState(store.getState().count)
  // 🍚使用useSelector获取数据 替代上面通过useState(store.getState().xxx)
  // const count = useSelector((state) => state.count)
  // 🍚使用useDispatch获取dispatch函数 之前需要通过store.dispatch({type: 'xxx'})
  // const dispatch = useDispatch()

  useEffect(() => {
    // 💥Redux只负责保存/计算state,不负责驱动视图
    // 💥React负责驱动视图
    const unFn = store.subscribe(() => {
      // 将Redux中的数据,同步到React的state中
      // setCount(store.getState().count)
    })
    return () => {
      // 组件卸载的时候接触监听
      unFn()
    }
  }, [])

  return (
    // 2. 使用dispatch修改redux中的state
    <>
      <div>
        <h2>子组件</h2>
        <h2>count: {count}</h2>
        {/* <button onClick={() => store.dispatch({ type: 'add', payload: 1 })}>【+1】</button> */}
        {/* // 使用useDispatch获取dispatch函数 eg: const dispatch = useDispatch(); */}
        <button onClick={() => store.dispatch({ type: 'add', payload: 1 })}>
          【+1】
        </button>
        <button onClick={() => store.dispatch({ type: 'des', payload: 1 })}>
          【-1】
        </button>
      </div>
    </>
  )
}

// 🍄使用React-Redux连接库,简化Redux在React中的使用

const divNode = (
  <div>
    <AppCom05 />
  </div>
)

root.render(divNode)

/**
 * Redux核心概念 - 总结
 * 1. state
 *  作用:保存数据 管理数据
 *
 * 2. action 💥
 *  本质:具有type字段的JS对象
 *  作用:描述发生了什么事情
 *
 * 3. dispatch 💥
 *  作用:触发一个事件
 *  本质:🛑修改state的唯一方法,调用dipatch(Action)
 *
 * 4. reducer函数
 * 作用:负责计算新的state
 * 签名:💥(state, action) => newState
 * 本质:
 *  1. 是一个函数,是一个纯函数
 *  2. 单项数据流
 *  3. 不可变数据,新值覆盖旧值
 *
 * 5. store
 * 以上内容综合就是store
 *
 */

posted @ 2023-03-23 14:12  Felix_Openmind  阅读(45)  评论(0)    收藏  举报
*{cursor: url(https://files-cdn.cnblogs.com/files/morango/fish-cursor.ico),auto;}