官方文档
TS版本请看:redux Toolkit(TypeScript版本)之基本使用
来消除手写Redux逻辑中的“样板文件”,防止常见错误,并提供简化标准Redux任务的API.
npm i redux @reduxjs/toolkit react-redux
Redux Toolkit 有一个名为 createSlice 的函数,它负责生成 action 类型字符串、action creator 函数和 action 对象的工作。您所要做的就是为这个切片定义一个名称,编写一个包含 reducer 函数的对象,它会自动生成相应的 action 代码。
import { createSlice } from '@reduxjs/toolkit'
const initialState = {
value: 0,
msg: '你好!'
}
export const counterSlice = createSlice({
name: 'counter',
initialState,
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
},
changeMsg: (state, action)=>{
state.msg += action.payload
}
},
})
// Action creators are generated for each case reducer function
export const { increment, decrement, incrementByAmount, changeMsg } = counterSlice.actions
export default counterSlice.reducer
// store.js
import { configureStore } from '@reduxjs/toolkit'
import counterSlice from './slice/counterSlice'
import testSlice from './slice/testSlice'
...
export const store = configureStore({
reducer: {
test: testSlice,
counter: counterSlice,
...
}
})
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
import 'antd/dist/antd.css'
import '../src/assets/css/common.less'
import { Provider } from 'react-redux'
import { store } from './redux/store'
ReactDOM.createRoot(document.getElementById('root')).render(
<Provider store={store}>
<App />
</Provider>
)
store.js
和counterSlice.js
见上文
// index.jsx
import React from 'react'
import { Button } from 'antd'
import Sub from '@/pages/Sub/index'
import { useDispatch, useSelector } from 'react-redux'
import { decrement, increment } from '@/redux/slice/counterSlice'
export default function Layout() {
const count = useSelector((state) => state.counter.value)
const dispatch = useDispatch()
return (
<div className='p-20'>
<div>
<Button
type="primary"
aria-label="Increment value"
onClick={() => dispatch(increment())}
>
Increment
</Button>
<span className='mlr-10'>{count}</span>
<Button
type="primary"
aria-label="Decrement value"
onClick={() => dispatch(decrement())}
>
Decrement
</Button>
</div>
<Sub></Sub>
</div>
)
}
import React from 'react'
import { Button } from 'antd'
import './sub.less'
import { useSelector, useDispatch } from 'react-redux'
import { increment, decrement, incrementByAmount, changeMsg } from '@/redux/slice/counterSlice'
function Sub() {
const count = useSelector((state) => state.counter.value)
const msg = useSelector(state => state.counter.msg)
const dispatch = useDispatch()
const handleIncrement = ()=>{
dispatch(increment())
}
return (
<div className="Sub">
<h2>Sub组件-counter值:{count}</h2>
<h2>Sub组件-counter值:{msg}</h2>
<Button
type="primary"
className='mr-10'
onClick={handleIncrement}
>
Increment
</Button>
<Button className='mr-10' onClick={()=>dispatch(decrement())}>decrement</Button>
<Button className='mr-10' onClick={()=>dispatch(incrementByAmount(10))}>incrementByAmount</Button>
<Button className='mr-10' onClick={()=>dispatch(changeMsg('世界'))}>改变msg</Button>
</div>
)
}
export default Sub