1. 环境搭建
插件安装:Redux Toolkit和react-redux
npm i @reduxjs/toolkit react-redux
2、
store目录结构设计
- 集中状态管理的部分会单独创建一个store目录(在src下)
- 应用通常会有很多个子模块,所以还会有个modules目录,在内部编写业务分类的子store
- store中的入口文件index.js的作用是组合modules中的所有子模块,并导出store
  
3、使用React Toolkit创建counterStore
创建各模块的store
 counterStore.js
import { createSlice } from "@reduxjs/toolkit";
// 创建store
const counterStore = createSlice({
	name: 'counter',
	// 初始化state
	initialState: {
		count: 0
	},
	// 修改状态的方法 
	reducers: {
		inscrement(state) {
			state.count++;
		},
		decrement(state) {
			state.count--;
		}
	}
})
// 结构出actionCreater函数
const {inscrement, decrement} = counterStore.actions
// 获取reducer
const reducer = counterStore.reducer
// 以按需导出的方式导出actionCreater
export {inscrement, decrement}
// 以默认导出的方式导出reducer
export default reducer
在index,js中组合store
import { configureStore } from "@reduxjs/toolkit";
// 导入子模块reducer
import counterReducer from './modules/counterStore'
const store = configureStore({
    reducer: {
        counter: counterReducer
    }
})
export default store
4、为React注入store
React-redux负责把Redux和redux连接起来,内置Provider组件通过store参数把创建好的store实例注入到应用中。
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>
);
reportWebVitals();
5、在React组件中使用store中的数据
使用useSelector钩子函数,把store中的数据映射到组件中
import React from 'react';
import './App.css';
import { useSelector } from 'react-redux';
function App() {
  // 这里state.counter和store中的reducer.counter是对应的
  const {count} = useSelector(state => state.counter);
  return (
    <React.Fragment>
      <div>
        {count}
      </div>
    </React.Fragment>
  );
}
export default App;
6、React组件中修改store中的数据
引入useDispatch钩子函数,作用:生成提交的action对象的dispatch函数
import React from 'react';
import './App.css';
import { useDispatch, useSelector } from 'react-redux';
// 倒入actionCreater
import {inscrement, decrement} from './store/modules/counterStore'
function App() {
  // 这里state.counter和store中的reducer.counter是对应的
  const {count} = useSelector(state => state.counter);
  const dispatch = useDispatch()
  return (
    <React.Fragment>
      <div>
        {/* 调用dispatch提交action对象 */}
        <button onClick={()=> dispatch(decrement())}> - </button>
        <span>
          {count}
        </span>
        <button onClick={() => dispatch(inscrement())}> + </button>
      </div>
    </React.Fragment>
  );
}
export default App;
7、在action中传参
在reducers的同步修改方法中添加action对象参数,在调用actionCreator时传递参数,参数会被传递到action对象的payload属性上
 定义方法:通过payload获取传入的参数
import { createSlice } from "@reduxjs/toolkit";
// 创建store
const counterStore = createSlice({
	name: 'counter',
	// 初始化state
	initialState: {
		count: 0
	},
	// 修改状态的方法 
	reducers: {
		inscrement(state) {
			state.count++;
		},
		decrement(state) {
			state.count--;
		},
		addToNum (state, action) {
			// payload是固定属性
			state.count = action.payload
		}
	}
})
// 解构出actionCreater函数
const {inscrement, decrement, addToNum} = counterStore.actions
// 获取reducer
const reducer = counterStore.reducer
// 以按需导出的方式导出actionCreater
export {inscrement, decrement, addToNum}
// 以默认导出的方式导出reducer
export default reducer
使用
        <button onClick={() => dispatch(addToNum(10))}> add To 10</button>
        <button onClick={() => dispatch(addToNum(20))}> add To 20</button>
8、异步代码
- store写法不变
- 单独封装一个函数,返回一个新函数,在新函数中:封装异步请求获取数据,并调用同步actionCreater传入异步数据生成一个action对象,并使用dispatch提交
 channelStore.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('http://geek.itheima.net/v1_0/channels')
		dispatch(setChannels(res.data.data.channels))
	}
}
const reducer = channelStore.reducer
export {fetchChannelList}
export default reducer
- 组件中dispatch的写法保持不变
 store/index.js不变
import { configureStore } from "@reduxjs/toolkit";
// 导入子模块reducer
import counterReducer from './modules/counterStore'
import channelReducer from './modules/channelStore'
const store = configureStore({
    reducer: {
        counter: counterReducer,
        channel: channelReducer
    }
})  
export default store
在组件中使用
import React, { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
// 倒入actionCreater
import { fetchChannelList } from './store/modules/channelStore';
function App() {
  const {channelList} = useSelector(state => state.channel)
  const dispatch = useDispatch()
  useEffect(() => {
    dispatch(fetchChannelList())
  }, [])
  return (
    <React.Fragment>
      <div>
        {/* 调用dispatch提交action对象 */}
        <ul>
          {channelList.map(item => <li key={item.id}>{item.name}</li>)}
        </ul>
      </div>
    </React.Fragment>
  );
}
export default App;


















