useSelector
import { useSelector } from "react-redux";
const account: IAccount = useSelector((state: IStateType) => state.account);
import {Provider} from "react-redux";
import store from "./store/store";
ReactDOM.render(<Provider store={store}><App /></Provider>,
document.getElementById('root'));
推荐使用 @reduxjs/toolkit 代替 createStore
store.ts
import { createStore, applyMiddleware, Store } from "redux";
import thunkMiddleware from "redux-thunk";
import rootReducers from "./reducers/root.reducer";
const store: Store = createStore(rootReducers, applyMiddleware(
thunkMiddleware
));
store.subscribe(() => {});
export default store;
@reduxjs/toolkit
zhuanlan.zhihu.com/p/382487951
import { configureStore } from '@reduxjs/toolkit';
import counterSlice from './slice/counterSlice';
export default configureStore({
reducer: {
counter: counterSlice,
}
})
createSlice
import { createSlice } from "@reduxjs/toolkit";
export const counterSlice = createSlice({
name: "counter", // 命名空间,在调用action的时候会默认的设置为action的前缀
// 初始值
initialState: {
count: 1,
title: "redux toolkit pre",
},
// 这里的属性会自动的导出为actions,在组件中可以直接通过dispatch进行触发
reducers: {
increment(state, { payload }) {
// console.log(action);
state.count = state.count + payload.step; // 内置了immutable
},
decrement(state) {
state.count -= 1;
},
},
});
// 导出actions
export const { increment, decrement } = counterSlice.actions;
// 内置了thunk插件,可以直接处理异步请求
export const asyncIncrement = (payload) => (dispatch) => {
setTimeout(() => {
dispatch(increment(payload));
}, 2000);
};
export default counterSlice.reducer; // 导出reducer,在创建store时使用到
• 在项目中使用
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import './index.css';
import App from './App';
import store from './store';
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
在组件内部,使用useState和useDispatch可以直接获取state数据与dispatch方法
import { useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { increment, asyncIncrement } from './store/features/counterSlice'; // 引入actions
function App() {
const { count } = useSelector((state) => state.counter);
const dispatch = useDispatch();
return (
<div className='App'>
<button
onClick={() => {
dispatch(increment({ step: 2 })); // dispatch派发action
}}
>
{count}
</button>
<hr />
<button
onClick={() => {
dispatch(asyncIncrement({ step: 1 }));
}}
>
{count}
</button>
</div>
);
}
export default App;
创建异步action
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
// createAsyncThunk创建一个异步的action,这个方法被触发的时候会有三个状态
// pending(进行中) fulfilled(成功) rejected(失败)
import { increment } from './counterSlice';
// 发起网络请求获取数据
const loadMoviesAPI = () =>
fetch(
'https://pcw-api.iqiyi.com/search/recommend/list?channel_id=1&data_type=1&mode=11&page_id=2&ret_num=48'
).then((res) => res.json());
// 这个action是可以直接调用的,用来处理异步操作获取数据
export const loadData = createAsyncThunk('movie/loadData', async () => {
const res = await loadMoviesAPI();
return res; // 此处的返回结果会在 .fulfilled中作为payload的值
});
export const movieSLice = createSlice({
name: 'movie',
initialState: {
list: [],
totals: 0,
},
reducers: {
loadDataEnd(state, { payload }) {
state.list = payload;
state.totals = payload.length;
},
},
// 可以额外的触发其他slice中的数据关联改变
extraReducers: {
[loadData.fulfilled](state, { payload }) {
console.log(payload);
state.list = payload.data.list;
},
[loadData.rejected](state, err) {
console.log(err);
},
[loadData.pending](state) {
console.log('进行中');
},
},
});
export const { loadDataEnd } = movieSLice.actions;
export default movieSLice.reducer;