参考代码:GitHub - leellun/zhiqu-web-test2
1 通过createAction创建Action做数据传递
在 Redux 中定义动作的常用方法是分别声明一个动作类型常量和一个动作创建器函数来构造该类型的动作。
store/action.ts
import { createAction } from "@reduxjs/toolkit";
const changeChannelAction2 = createAction('changeChannelAction2', (text: string)=> {
return {
payload: {
name:text
} as any,
}
})
export { changeChannelAction2 };
通过createSlice创建切片状态:store/slice.ts
通过builder.addCase("changeChannelAction2",fn)接收type为changeChannelAction2的数据
import { createSlice } from "@reduxjs/toolkit";
const channelSlice = createSlice({
name:"channel",
initialState:{
channel:{
name:'3345345'
}
},
reducers:{
},
extraReducers:(builder)=>{
builder.addCase("changeChannelAction2",(state,action:any)=>{
console.log("=234=234")
state.channel.name=action.payload.name
})
}
})
const { changeChannel } = channelSlice.actions;
const channelReducer = channelSlice.reducer;
export {changeChannel,channelReducer}
然后通过dispatch分发数据
store.dispatch(changeChannelAction2("sdf"))
控制台将会打印
=234=234
2 通过createAsyncThunk异步加载数据,并且传递数据
import { createAsyncThunk } from "@reduxjs/toolkit";
const changeChannelAction = createAsyncThunk(
'changeChannelAction',
async (extraInfo: { userId: string }, { dispatch }) => {
const { userId } = extraInfo;
return userId+"====createAsyncThunk="
}
);
export { changeChannelAction };
3 通过createReducer处理数据和状态化数据
import { createReducer } from "@reduxjs/toolkit";
const userReducer = createReducer(
{
id:'',
name:"sdfsdf"
},
(builder) => {
builder
.addCase("changeChannelAction2", (state, action:any) => {
console.log(action.payload.name)
state.name = action.payload.name;
})
}
);
export default userReducer;
4 多type数据处理状态化
const moreReducer = (state:any, action: any) => {
state=action.payload
console.log("moreReducer",state)
if(state===undefined){
return {}
}
switch (action.type) {
case 'changeChannelAction':
return state;
case 'changeChannelAction2':
return state;
default:
return state;
}
};
export default moreReducer;
5 同步方法指定类型和载体
export function changeUserMsg(payload: any) {
return {
type: 'changeChannelAction',
payload
};
}
store.dispatch(changeUserMsg({name:''}))
6 异步方法指定类型和载体
export function changeAsyncUserMsg(payload: any) {
return async (dispatch:any)=>{
dispatch(changeUserMsg(payload))
};
}
7 获取store中的数据
const CounterComponent = () => {
const name = useSelector((state:any) => {
return state.channelReducer.channel.name
})
return <div>{name}</div>
}
8 将store和组件结合
<Provider store={store}>
</Provider>
可以在Provider作用访问类使用useDispatcher()
完整代码:
store/action.ts
import { createAction } from "@reduxjs/toolkit";
const changeChannelAction2 = createAction('changeChannelAction2', (text: string)=> {
return {
payload: {
id:'',
name:text
} as any,
}
})
export { changeChannelAction2 };
store/reducer.ts
import { createReducer } from "@reduxjs/toolkit";
const userReducer = createReducer(
{
id:'',
name:"sdfsdf"
},
(builder) => {
builder
.addCase("changeChannelAction2", (state, action:any) => {
console.log(action.payload.name)
state.name = action.payload.name;
})
}
);
export default userReducer;
store/thunk.ts
import { createAsyncThunk } from "@reduxjs/toolkit";
const changeChannelAction = createAsyncThunk(
'changeChannelAction',
async (extraInfo: { userId: string }, { dispatch }) => {
const { userId } = extraInfo;
return userId+"====createAsyncThunk="
}
);
export { changeChannelAction };
store/slice.ts
import { createSlice } from "@reduxjs/toolkit";
import { changeChannelAction } from "./thunk";
const channelSlice = createSlice({
name:"channel",
initialState:{
channel:{
id:'',
name:'3345345'
}
},
reducers:{
changeChannel(state, { payload }) {
console.log(payload)
state.channel = payload;
}
},
extraReducers:(builder)=>{
builder.addCase(changeChannelAction.pending, (state, action:any) => {
console.log(action.payload,"===1")
})
builder.addCase(changeChannelAction.fulfilled, (state, action:any) => {console.log(action.payload,"===2")})
builder.addCase(changeChannelAction.rejected, (state, action:any) => {console.log(action.payload,"===3")})
builder.addCase("changeChannelAction2",(state,action:any)=>{
console.log("=234=234")
state.channel.name=action.payload.name
})
}
})
const { changeChannel } = channelSlice.actions;
const channelReducer = channelSlice.reducer;
export {changeChannel,channelReducer}
store/moreReducer.ts
const moreReducer = (state:any, action: any) => {
state=action.payload
console.log("moreReducer",state)
if(state===undefined){
return {}
}
switch (action.type) {
case 'changeChannelAction':
return state;
case 'changeChannelAction2':
return state;
default:
return state;
}
};
export default moreReducer;
store/method.ts
export function changeUserMsg(payload: any) {
return {
type: 'changeChannelAction',
payload
};
}
export function changeAsyncUserMsg(payload: any) {
return async (dispatch:any)=>{
dispatch(changeUserMsg(payload))
};
}
store/index.ts
import { configureStore } from "@reduxjs/toolkit";
import {changeChannel, channelReducer} from './slice'
import userReducer from './reducer'
import moreReducer from './moreReducer'
const store = configureStore({
reducer: {
channelReducer,
userReducer,
moreReducer
},
devTools: true
});
export default store;
app.tsx
import React, { useCallback, useState } from 'react';
import logo from './logo.svg';
import './App.css';
import { Provider, useSelector } from 'react-redux';
import store from './store';
import { changeChannelAction2 } from './store/action';
import { changeChannelAction } from './store/thunk';
import { changeChannel } from './store/slice';
import { changeAsyncUserMsg, changeUserMsg } from './store/method';
function App() {
const [count, setCount] = useState(0);
const handleClick = useCallback(() => {
console.log(`Clicked ${count} times`);
}, [count]);
store.dispatch(changeChannelAction({userId:"234234243"}))
store.dispatch(changeChannelAction2("sdf"))
store.dispatch(changeChannel({id:"23",name:"test3"}))
store.dispatch(changeUserMsg("aaaaaaaaa"))
store.dispatch(changeAsyncUserMsg("bbbbbbbb"))
const CounterComponent = () => {
const name = useSelector((state:any) => {
return state.channelReducer.channel.name
})
return <div>{name}</div>
}
return (
<div className="App">
<Provider store={store}>
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.tsx</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
<div>Count: {count}</div>
<button onClick={() => setCount(count + 1)}>Increment</button>
<button onClick={handleClick}>Click me</button>
<CounterComponent/>
</Provider>
</div>
);
}
export default App;
推荐文章: