Redux、Store、React Redux关系&使用

1,196 阅读2分钟

创建React Store

创建名为 src/app/store.js的文件,并从Redux工具库中引入configureStore API。如此可创建一个空的Redux store并导出,如下:

app/store.js

import { configureStore } from '@reduxjs/toolkit'

export default configureStore({
  reducer: {},
})

React使用Redux Store

React组件通过React Redux的Provider组件使用store,store作为Provider的props传递(其中store是用户创建的??)。代码示例:

app/store.js

import React from 'react'
import ReactDOM from 'react-dom'
import './index.css'
import App from './App'
import store from './app/store'
import { Provider } from 'react-redux'

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
)

Redux State Slice

通过Redux Toolkit中的createSlice API创建一个state slice,其中需要三个核心要素:标识slice唯一性的string name、初始化的state、更新state的reducer方法。slice的创建采用immer语法。创建后,即可export actions和reducer方法。

slice是不可变的语法/模板,但Redux Toolkit的createSlicecreateReducer APIs 使用Immer可以更新

features/counter/counterSlice.js

import { createSlice } from '@reduxjs/toolkit'

export const counterSlice = createSlice({
  name: 'counter',
  initialState: {
    value: 0,
  },
  reducers: {
    increment: (state) => {
      // Redux Toolkit allows us to write "mutating" logic in reducers. It
      // doesn't actually mutate the state because it uses the Immer library,
      // which detects changes to a "draft state" and produces a brand new
      // immutable state based off those changes
      state.value += 1
    },
    decrement: (state) => {
      state.value -= 1
    },
    incrementByAmount: (state, action) => {
      state.value += action.payload
    },
  },
})

// Action creators are generated for each case reducer function
export const { increment, decrement, incrementByAmount } = counterSlice.actions

export default counterSlice.reducer

Slice Reducers应用到Store

下一步将slice中的reducer方法应用到store。不同于第一步的创建空store,借助slice reducer可定义一个key为reducers的对象,store通过reducer方法更新slice中的state

app/store.js

import counterReducer from '../features/counter/counterSlice'

export default configureStore({
  reducer: {
    counter: counterReducer,
  },
})

React组件中使用State和Actions

这里React Redux的hook API发挥作用,使用useSelector从store取数据,使用useDispatch 分发actions

features/counter/Counter.js

import { useSelector, useDispatch } from 'react-redux'
import { decrement, increment } from './counterSlice'
import styles from './Counter.module.css'

export function Counter() {
  const count = useSelector((state) => state.counter.value)
  const dispatch = useDispatch()

  return (
    <div>
      <div>
        <button
          aria-label="Increment value"
          onClick={() => dispatch(increment())}
        >
          Increment
        </button>
        <span>{count}</span>
        <button
          aria-label="Decrement value"
          onClick={() => dispatch(decrement())}
        >
          Decrement
        </button>
      </div>
    </div>
  )
}

总结&补充

slice: 定义state/数据集、action/更新state的方法、reducer方法 store: 隔离slice和组件, 其他组件派发/dispatch行为/actions给store,通过store更新state;其他组件订阅store中的状态state更新视图 react-redux: