Redux

在React中使用Redux

React项目中,使用Redux的主要原因和优点

        

  1. 单一数据源和状态管理:Redux提供了一个全局的、单一的状态树来管理整个应用的状态。这使得状态的管理更加集中和一致,减少了组件之间通过props进行状态传递的复杂性。React本质上是一个UI库,其数据流是单向的,即从父组件流向子组件。当项目中的数据变得复杂时,Redux可以帮助更好地管理这些数据。
  2. 可预测和可维护的状态变化:Redux强制使用纯函数(即reducer)来更新状态,这确保了状态变化的可预测性和可追踪性。由于状态的变化只能通过reducer进行,并且每次变化都会生成一个新的状态对象,因此可以轻松地跟踪和调试状态的变化。此外,这种强制性的更新方式也使得代码更易于维护和测试。
  3. 跨组件状态同步:Redux允许组件在不同层次结构中共享状态,并在状态变化时得到通知。这在需要实时反应全局状态变化的场景中非常有用,如实时通知、用户登录状态等。
  4. 中间件支持:Redux提供了中间件机制,允许在状态更新的过程中执行额外的逻辑。这使得Redux能够很好地处理异步操作,如API调用、数据获取等。通过结合如Redux Thunk、Redux Saga等中间件,异步操作变得更加可控和可测试。
  5. 时间旅行和调试:Redux通过在状态更改历史中保留每个动作的快照,使得可以轻松地进行时间旅行式的调试。这意味着可以回放应用状态的历史,以便找到错误或理解应用程序行为。
  6. 社区与生态圈:Redux拥有庞大的社区和丰富的生态圈,这为其提供了大量的支持和资源。这使得Redux在开发过程中更容易找到解决方案和最佳实践。

使用

        下载依赖包

        

npm i react-redux @reduxjs/toolkit

假设我们这边需要设置一个count值存储在redux中 使用按钮去修改它的值

1.首先我们需要在模块中创建一个文件  例如 /src/store/moudle/counterSlice.jsx
import {createSlice} from "@reduxjs/toolkit";

const counterSlice = createSlice({
//必须要给这个文件起一个名字
    name: "counter",  

    initialState: {
        count: 0,  //计数字段
    },

//同步数据信息
    reducers: {
        // 不传入参数
        increment(state) {
            state.count += 1;
        },
        decrement(state) {
            if (state.count <= 0) {
                state.count = 0;
                return
            }
            state.count -= 1;
        },

        // 传入参数
        incrementByAmount(state, action) {
            state.count += action.payload;
        },
        decrementByAmount(state, action) {
            state.count -= action.payload
            if (state.count <= 0) {
                state.count = 0;
            }
        },

    },
})

export const {increment, decrement, incrementByAmount, decrementByAmount} = counterSlice.actions;
export default counterSlice.reducer;
        2.然后我们创建store管理注册仓库    文件创建在/src/store/index.jsx文件中
import { configureStore } from '@reduxjs/toolkit';
import countReducer from "./module/counterSlice";
const store =configureStore({
    reducer: {
        counter: countReducer,   // counter 这个名字不能乱取  因为后面取值就要靠这个来取
    },

});
export default store;

3.其次就是我们使用了 文件放在/src/page/count/index.jsx

import {Button} from "antd";

import {increment, decrement, incrementByAmount, decrementByAmount} from '../../store/module/counterSlice'
import {useDispatch, useSelector} from "react-redux";
import {PlusOutlined, MinusOutlined} from "@ant-design/icons";


function CountIndex() {
    // 导入并使用他  获取dispatch 去执行redux中的方法
    const dispatch = useDispatch()
    // 取出存入Redux中的数据信息 counter就是在store注册的时候起的名字
    
    const count = useSelector(state => state.counter.count);

    return (
        <div>
            <div style={{display: 'flex', justifyContent: 'space-between', alignItems: 'center'}}>
                <Button type="primary" ghost icon={<PlusOutlined/>} onClick={() => dispatch(increment())}></Button>
                <Button type="primary" ghost style={{marginLeft: 10}}
                        onClick={() => dispatch(incrementByAmount(10))}>加10</Button>
                <h3 style={{color: "green"}}>{count}</h3>
                <Button danger ghost icon={<MinusOutlined/>} onClick={() => dispatch(decrement())}></Button>
                <Button danger ghost style={{marginLeft: 10}}
                        onClick={() => dispatch(decrementByAmount(10))}>减10</Button>
            </div>
        </div>
    )
}

export default CountIndex
3.在index.js中注册
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import store from './store';
import {Provider} from 'react-redux';


import reportWebVitals from './reportWebVitals';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
   
        <Provider store={store}>
               <App/>
        </Provider>
   
);

reportWebVitals();
4.效果图

异步获取数据信息

5.这里都是我们的同步数据  如果我们需要异步请求获取数据的话 需要这个写
// 异步获取数据信息

//getDataInfo是你的同步方法写法相当与带参的使用action.payload赋值
const {getDataInfo} = counterSlice.actions

const fetchData = () => {
    return async (dispatch) => {
        if (!counterSlice.getInitialState().table){
            return
        }
        const response = await axios.post(url)
        dispatch(getDataInfo(response.data.data))
    }
}

export{fetchData }

使用的话跟之前一样 dispatch(函数名)

假设页面加载获取


    useEffect(() => {
        function init() {
            dispatch(fetchData())
        }

        init()
    }, [dispatch])

全部代码 

1./src/page/count/index.jsx
import {Button, Card, Pagination} from "antd";

import {increment, decrement, incrementByAmount, decrementByAmount} from '../../store/module/counterSlice'
import {useDispatch, useSelector} from "react-redux";
import {fetchData} from "../../store/module/counterSlice";
import {useEffect} from "react";
import {Table, Tag} from "antd";
import {PlusOutlined, MinusOutlined} from "@ant-design/icons";
import {useNavigate} from "react-router-dom";
import {isAnyOf} from "@reduxjs/toolkit";

const columns = [
   //自定义
]

function CountIndex() {
    const dispatch = useDispatch()
    const navigate = useNavigate();
    useEffect(() => {
        function init() {
            dispatch(fetchData())
        }

        init()
    }, [dispatch])
    // 取出存入Redux中的数据信息
    const table = useSelector(state => state.counter.table)
    const count = useSelector(state => state.counter.count);
 
    // params  1 分页信息  2 自定义列过滤器  3 排序信息   4 数据信息
    const handleChange = (pagination, filters, sorter, extra) => {
    }
    return (
        <div>
            <div style={{display: 'flex', justifyContent: 'space-between', alignItems: 'center'}}>
                <Button type="primary" ghost icon={<PlusOutlined/>} onClick={() => dispatch(increment())}></Button>
                <Button type="primary" ghost style={{marginLeft: 10}}
                        onClick={() => dispatch(incrementByAmount(10))}>加10</Button>
                <h3 style={{color: "green"}}>{count}</h3>
                <Button danger ghost icon={<MinusOutlined/>} onClick={() => dispatch(decrement())}></Button>
                <Button danger ghost style={{marginLeft: 10}}
                        onClick={() => dispatch(decrementByAmount(10))}>减10</Button>
            </div>
            {table &&
                <Card bordered={false} style={{backgroundColor: '#808080', width: '1020px', height: '520px'}}>
                    <Table dataSource={table} rowKey="dataId" columns={columns}
                           onChange={handleChange} style={{height: '400px'}} size='small'>
                    </Table>
                </Card>
            }
        </div>
    )
}

export default CountIndex
2. /src/store/moudle/counterSlice.jsx

import {createSlice} from "@reduxjs/toolkit";
import axios from "axios";

const counterSlice = createSlice({
    name: "counter",
    initialState: {
        count: 0,  //计数字段
        table: []  //表格数据
    },
    reducers: {
        increment(state) {
            state.count += 1;
        },
        decrement(state) {
            if (state.count <= 0) {
                state.count = 0;
                return
            }
            state.count -= 1;
        },
        incrementByAmount(state, action) {
            state.count += action.payload;
        },
        decrementByAmount(state, action) {
            state.count -= action.payload
            if (state.count <= 0) {
                state.count = 0;
            }
        },
        getDataInfo(state, action) {
            state.table = action.payload;
        },
        setDataInfo(state, action) {
            state.table = action.payload;
        }
    },
})

// 异步获取数据信息
const {getDataInfo} = counterSlice.actions

const fetchData = () => {
    return async (dispatch) => {
        if (!counterSlice.getInitialState().table){
            return
        }
        const response = await axios.post(url)
        dispatch(getDataInfo(response.data.data))
    }
}

// 分别导出 同步 异步 默认导出小仓库
export const {increment, decrement, incrementByAmount, decrementByAmount,setDataInfo} = counterSlice.actions;
export {fetchData}
export default counterSlice.reducer;

  • 18
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值