React基础之Redux
React基础之Redux
Redux是React中最常用的集中状态管理工具,类似于vue中的Pinia或是vuex,可以独立于框架运行
需要先安装两个插件
Redux Toolkit:简写书写方式
react-redux:连接Redux与React组件的中间件
安装
npm i @reduxjs/toolkit react-redux
创建一个store目录结构index导出子模块,再创建一个modules目录,用于存放index.js的所有子模块
实例代码
项目结构
首先,在countStore.js中
import
{
createSlice
}
from
“@reduxjs/toolkit”
;
const
countStore
=
createSlice
({
name:
‘counter’
,
//
初始化状态
initialState:
{
count:
0
},
//
编写修改数据的方法 同步方法,支持直接修改
reducers:
{
increment
(
state
) {
state
.
count
++
},
decrement
(
state
){
state
.
count
–
}
}
})
//解构出来actionCreater函数
const
{
increment
,
decrement
}=
countStore
.
actions
//获取reducer
const
reducer
=
countStore
.
reducer
//按需导出的方式导出actionCreater
export
{
increment
,
decrement
}
//以默认导出的方式导出reducer
export default
reducer
在store的导出index.js中
import
{
configureStore
}
from
“@reduxjs/toolkit”
;
//导入子模块reducer
import
counterStore
from
‘./modules/counterStore’
const
store
=
configureStore
({
reducer:
{
counter
:
counterStore
}
})
export default
store
在主入口index.js中
import
React
from
‘react’
;
import
ReactDOM
from
‘react-dom/client’
;
import
‘./index.css’
;
import
App
from
‘./App’
;
import
reportWebVitals
from
‘./reportWebVitals’
;
import
store
from
‘./store’
;
import { Provider } from ‘react-redux’ ;
const
root
=
ReactDOM
.
createRoot
(
document
.
getElementById
(
‘root’
));
root
.
render
(
<
React.StrictMode
< Provider store = { store } >
< App />
</ Provider >
</
React.StrictMode
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more:
reportWebVitals
();
在需要使用redux的app.js中
import
React
, {
useState
}
from
‘react’
;
import
{
useEffect
}
from
‘react’
;
import
{
useDispatch
,
useSelector
}
from
‘react-redux’
;
//导入actionCreeater
import
{
increment
,
decrement
}
from
‘./store/modules/counterStore’
;
function
App
() {
const
{
count
}=
useSelector
(
state
=>
state
.
counter
)
const
dispatch
=
useDispatch
()
return
(
<
div
<
button
onClick
=
{
()
=>
dispatch
(
decrement
())
}
–
</
button
{
count
}
<
button
onClick
=
{
()
=>
dispatch
(
increment
())
}
++
</
button
</
div
);
}
export default
App
;
提交 action 传参
首先在reducers方法中,新增一个方法,并且多一个参数,在其他地方调用这个方法的时候,传递对于的参数即可
首先,在countStore.js中
import
{
createSlice
}
from
“@reduxjs/toolkit”
;
const
countStore
=
createSlice
({
name:
‘counter’
,
//
初始化状态
initialState:
{
count:
0
},
//
编写修改数据的方法 同步方法,支持直接修改
reducers:
{
increment
(
state
) {
state
.
count
++
},
decrement
(
state
){
state
.
count
–
},
addtoNum
( state , action
){
state
.
count
=
action
.
payload
}
}
})
//解构出来actionCreater函数
const
{
increment
,
decrement
,
addtoNum
}=
countStore
.
actions
//获取reducer
const
reducer
=
countStore
.
reducer
//按需导出的方式导出actionCreater
export
{
increment
,
decrement
,
addtoNum
}
//以默认导出的方式导出reducer
export default
reducer
在store的导出index.js中
import
{
configureStore
}
from
“@reduxjs/toolkit”
;
//导入子模块reducer
import
counterStore
from
‘./modules/counterStore’
const
store
=
configureStore
({
reducer:
{
counter
:
counterStore
}
})
export default
store
在主入口index.js中
import
React
from
‘react’
;
import
ReactDOM
from
‘react-dom/client’
;
import
‘./index.css’
;
import
App
from
‘./App’
;
import
reportWebVitals
from
‘./reportWebVitals’
;
import
store
from
‘./store’
;
import { Provider } from ‘react-redux’ ;
const
root
=
ReactDOM
.
createRoot
(
document
.
getElementById
(
‘root’
));
root
.
render
(
<
React.StrictMode
< Provider store = { store } >
< App />
</ Provider >
</
React.StrictMode
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more:
reportWebVitals
();
在需要使用redux的app.js中
import
React
, {
useState
}
from
‘react’
;
import
{
useEffect
}
from
‘react’
;
import
{
useDispatch
,
useSelector
}
from
‘react-redux’
;
//导入actionCreeater
import
{
increment
,
decrement
,
addtoNum
}
from
‘./store/modules/counterStore’
;
function
App
() {
const
{
count
}=
useSelector
(
state
=>
state
.
counter
)
const
dispatch
=
useDispatch
()
return
(
<
div
<
button
onClick
=
{
()
=>
dispatch
(
decrement
())
}
–
</
button
{
count
}
<
button
onClick
=
{
()
=>
dispatch
(
increment
())
}
++
</
button
<
button
onClick
=
{
()
=>
dispatch
( addtoNum ( 10 )
)
}
addTo10
</
button
<
button
onClick
=
{
()
=>
dispatch
( addtoNum ( 20 )
)
}
addTo20
</
button
</
div
);
}
export default
App
;
异步状态操作
将异步方法定义到store中,使用axios发送请求
channeStore.js为
import
{
createSlice
}
from
“@reduxjs/toolkit”
;
import
axios
from
“axios”
;
const
channelStore
=
createSlice
({
name:
‘channel’
,
initialState:
{
channelList:
[]
},
reducers:
{
setChannels
(
state
,
action
){
state
.
channelList
=
action
.
payload
}
}
})
const
{
setChannels
}=
channelStore
.
actions
//异步请求部分
const
fetchChannelList
=()
=>
{
return
async
(
dispatch
)
=>
{
const
res
=
await
axios
.
get
(
‘
)
dispatch
(
setChannels
(
res
.
data
.
data
.
channels
))
}
}
export
{
fetchChannelList
}
const
reducers
=
channelStore
.
reducer
export default
reducers
store下的index.js为
import
{
configureStore
}
from
“@reduxjs/toolkit”
;
//导入子模块reducer
import
channelStore
from
‘./modules/channelStore’
const
store
=
configureStore
({
reducer:
{
channel
:
channelStore
}
})
export default
store
src下的index.js为
import
React
from
‘react’
;
import
ReactDOM
from
‘react-dom/client’
;
import
‘./index.css’
;
import
App
from
‘./App’
;
import
reportWebVitals
from
‘./reportWebVitals’
;
import
store
from
‘./store’
;
import
{
Provider
}
from
‘react-redux’
;
const
root
=
ReactDOM
.
createRoot
(
document
.
getElementById
(
‘root’
));
root
.
render
(
<
React.StrictMode
<
Provider
store
=
{
store
}
<
App
/>
</
Provider
</
React.StrictMode
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more:
reportWebVitals
();
App.js为
import
{
useEffect
}
from
‘react’
;
import
{
useDispatch
,
useSelector
}
from
‘react-redux’
;
import
{
fetchChannelList
}
from
‘./store/modules/channelStore’
;
function
App
() {
const
dispatch
=
useDispatch
()
const
{
channelList
} =
useSelector
(
state
=>
state
.
channel
)
//
使用
useEffect
触发异步请求
useEffect
(()
=>
{
dispatch
(
fetchChannelList
())
},[
dispatch
])
return
(
<
div
<
ul
{
channelList
.
map
(
item
=>
<
li
key
=
{
item
.
id
}
{
item
.
name
}
</
li
)
}
</
ul
</
div
);
}
export default
App
;