• Redux和@reduxjs/toolkit的使用


    1. 简介:

    Redux 是一种用于管理应用程序状态的 JavaScript 库。它是一个可预测的状态容器,可以用于编写
    可维护和可扩展的应用程序。
    @reduxjs/toolkit 是一个官方提供的 Redux 工具包,它可以帮助简化 Redux 应用程序的开发,并
    提供常用的 Redux 原生方法,例如创建 Redux store、定义 reducer、处理异步操作等。

    2. 用法(同步)

    首先,我们需要安装 @reduxjs/toolkit 和 react-redux

    npm install @reduxjs/toolkit react-redux -S
    
    1> 引入Provider,对根目录进行一个包装
    import { Provider } from 'react-redux';
    import store from './store/index.js';
    const root = ReactDOM.createRoot(document.getElementById('root'));
    root.render(
        <Provider store={srore}>
            <App />
        Provider>
    );
    
    2> 编写store文件,利用@reduxjs/toolkit工具的configureStore创建store
    import { configureStore } from '@reduxjs/toolkit';
    import userReducer from './reducers/user';
    const store = configureStore({
        reducer: {
            user: userReducer
        }
    });
    export default store;
    
    3> 编写store下的reducers/user文件
    import { createSlice } from '@reduxjs/toolkit';
    let userSlice = createSlice({
        name: 'user',
        initialState: {
            isLogin: false,
            loginCount: 0,
    	test: ''
        },
        reducers: {
            addLoginCount(state) {
                state.loginCount++;
            },
            addLoginCountByNum(state, action) {
                state.loginCount += action.payload;
            }
        },
        extraReducers(builder) { // 异步的处理
            // 当getTest fulfilled状态时,处理
            builder.addCase(getTest.fulfilled, (state, { payload }) => {
                // 上述方法返回的结果payload
                state.test = payload;
            })
        }
    });
    // 外部组件来使用的action
    export const { addLoginCount, addLoginCountByNum } = userSlice.actions;
    // 默认导出是所有的reducer 供store注册这些方法
    export default userSlice.reducer;
    
    4> 使用store
    import './App.css';
    import { useState, memo } from 'react';
    // 取出行为
    import { addLoginCount, addLoginCountByNum } from './store/reducers/user';
    import { useDispatch, useSelector } from 'react-redux';
    
    // 在子组件中使用
    // 这里的memo保证props发生变化时,才更新
    const Son = memo(() => {
        console.log('子组件更新.....')
        const user = useSelector(state => state.user);
        return <h1>我是子组件{user.loginCount}h1>
    })
    function App() {
        const user = useSelector(state => state.user);
        const dispath = useDispatch();
        const [num, setNum] = useState(1);
        return (
            <div className="App">
                {user.isLogin ? 'TRUE' : 'FALSE'} || {user.loginCount} || {num}
                <button onClick={e => dispath(addLoginCount())}>更改loginCount+1button>
                <button onClick={e => dispath(addLoginCountByNum(10))}>更改loginCountbutton>
                <button onClick={e => setNum(num + 1)}>变更父组件button>
                <Son />
            div>
        );
    }
    export default App;
    

    memo用法补充:
    就如上边代码,在没有用memo包装前,每次修改num的值时,子组件都会随着更新。用memo包装后,组件Son不会随num值的改变而更新。但如果num的值传给了Son组件(),Son组件也会跟随num的值的修改而更新了。大幅度使用会造成缓存越来越大,针对组件大一点且使用频率不是很高的情况下去使用。

    以上是同步的用法,下边记录下异步的用法:

    3. 用发(异步)

    1> 首先就是就是借助@reduxjs/toolkit工具库的createAsyncThunk方法,在reducers/user文件中新增一个getTest方法模拟获取数据如下:
    export const getTest = createAsyncThunk('user/getTest', async () => {
        let res = await fetch('http://localhost:3001/');
        let text = await res.text();
        console.log('text::', text)
        return text;
    });
    

    说明:上边用的fetch是ES6里新增的一个发请求的api。

    2>在reducers统计中添加extraReducers的回调,其接收一个builder的参数,通过builder的addCase方法,可以根据上边定义的getTest方法的状态 (这里也就是Promise的三种状态pending/rejection/fulfilled) 去处理数据,如上边代码中的:
    extraReducers(builder) { // 异步的处理
            // 当getTest fulfilled状态时,处理
            builder.addCase(getTest.fulfilled, (state, { payload }) => {
                // 上述方法返回的结果payload
                state.test = payload;
            })
    }
    
    3>使用
    function App() {
        const user = useSelector(state => state.user);
        const dispath = useDispatch();
        useEffect(() => {
            dispath(getTest());
        }, [])
        return (
            <div className="App">
                <pre>
                    {user.test}
                pre>
                {user.isLogin ? 'TRUE' : 'FALSE'}
            div>
        );
    }
    
  • 相关阅读:
    Monkey测试
    camx 主要接口
    Spring ApplicationListener监听器用法
    Kotlin学习快速入门(7)——扩展的妙用
    6_ROS话题消息(Topic)
    mysql中添加字段
    【python】python面向对象——类的使用
    PyQt学习笔记-获取Hash值的小工具
    大健康产业商业供应链管理系统:采购管理规范化,提高企业采购效益
    详解sed命令与awk命令
  • 原文地址:https://www.cnblogs.com/lvkehao/p/17991525