zoukankan      html  css  js  c++  java
  • 使用react-redux

      使用react-redux能让我们组件之间互相通信,并且相比较以前的写法,更加的简单明了。在使用前,我们需要npm install一下react-redux以及reduxjs/toolkit

    一、添加react-redux和reduxjs/toolkit

    npm install react-redux
    
    注意:如果找不到模块,再执行npm install @types/react-redux一下即可

      详细内容可参考https://github.com/reduxjs/react-redux

     npm install @reduxjs/toolkit

      详细内容可参考https://www.npmjs.com/package/@reduxjs/toolkit

    二、了解react-redux和reduxjs/toolkit的几个API

      Provider:react-redux 提供Provider组件,可以让容器组件拿到state。

      store :作为一个 prop 传给 Provider 组件。

      useSelector:从redux的store对象中获取数据(state)。

     使用方法:const result:any= useSelector(selector:Function,equalityFn?:Function)

      useDispatch:返回redux store中对dispatch函数的引用。

     使用方法:const dispatch = useDispatch()    dispatch(方法)   

      configureStore():包装createStore以提供简化的配置选项和良好的默认值。它可以自动组合您的碎片,添加您提供的任何Redux中间件,默认情况下包括Redux -thunk,并支持使用Redux DevTools扩展。

    三、开始撸redux的demo

      1、创建store

      首先在src文件夹下创建store文件夹,并创建index.ts文件。因为reduxjs/toolkit是碎片化,所以需要使用configureStore将碎片组合起来,以便维护。在index文件中的代码如下:

     import { configureStore } from '@reduxjs/toolkit';
     export default configureStore({
        reducer: {
        },
      });

      2、引入Provider,将store作为props传递给子组件

      import { Provider } from 'react-redux'
      import store from '@src/store'
      ReactDOM.render(
        <Provider store={store}>
          <ConfigProvider locale={zh_CN}>
            <Route />
          </ConfigProvider >
        </Provider>,
        document.getElementById('root')
      );

      3、经典的计数器Demo

      需求:数字的默认值为0,点击加1按钮,数字加1,减1按钮,数字减1。

      首先,在store文件夹下创建一个counterSlice文件,并引入createSlice

    import { createSlice } from '@reduxjs/toolkit'

      然后创建一个counterSlice碎片

    export const counterSlice = createSlice({
      name: 'counter',          //碎片名称
      initialState: {           //碎片的默认值
        value: 0,
      },
      reducers: {             //方法
        increment: (state) => {    //增加1函数
          state.value += 1;
        },
        decrement: (state) => {    //减少1函数
          state.value -= 1;
        },
      },
    });

      最后将increment,decrement添加到action,并且声明一个变量selectCount,导出这个碎片。

      export const { increment, decrement } = counterSlice.actions;
      export const selectCount = (state: any) => state.counter.value;
      export default counterSlice.reducer;

      注:将increment,decrement添加到action,外部可直接调用,并且会自动触发reducers,并且返回最新的state

      创建counterSlice碎片后,需要在store的index文件中,将这个碎片组合起来。

      import { configureStore } from '@reduxjs/toolkit';
      import counterSlice from './counterSlice'
      export default configureStore({
        reducer: {
          counter: counterSlice      //碎片的name:碎片
        },
      });

       如何在我们需要的地方使用呢?这种情况下就需要使用useSelectoruseDispatch了。完整的代码以及注释如下:

    import React from 'react';
    import { useSelector, useDispatch } from 'react-redux';             //引入useSelector以及useDispatch
    import { selectCount, increment, decrement } from '@src/store/counterSlice';    //引入counterSlice碎片中的变量以及函数
    import { Button } from 'antd' export default () => { const count = useSelector(selectCount); //获取count的值,会随着按钮的点击而改变 const dispatch = useDispatch()            return (
    <div> <p>count的值是{count}</p>         <Button onClick={() => dispatch(increment())}>加1</Button>      //点击加1按钮时,触发increment   <Button onClick={() => dispatch(decrement())}>减1</Button>      //点击减1按钮时,触发decrement </div> ); }

      到这,简单的一个demo就完成了。

    四、优化计数器Demo

      有时候需要请求接口之后,再执行其他操作,这就需要异步进行操作。下面来模拟一个简单的异步操作。

      1、在reducers中添加需要的函数,并添加到action

      incrementAsyncCount: (state, action) => {
          // console.log(action)   输出结果: {type: "counter/incrementAsyncCount",payload: 1}
          state.value += action.payload;
      },
    
    
      export const { incrementAsyncCount } = counterSlice.actions;

      2、添加请求函数(使用延迟计时器模拟)

      export const incrementAsync = (num: number) => (dispatch: any) => {
        //可以在这里发送请求,当请求结束之后,再执行reducers
        setTimeout(() => {
          dispatch(incrementAsyncCount(num));
        }, 2000);
      };

      3、在相应页面触发

      import { incrementAsync } from '@src/store/counterSlice';            //首先引入该函数
    
      <Button onClick={() => dispatch(incrementAsync(1))}>延迟2秒加1 </Button>  //点击按钮时触发

      这样设置完成之后,每次点击按钮,2秒之后,count的值才会加1。

    五、完整Demo

    import React from 'react';
    import ReactDOM from 'react-dom';
    import zh_CN from 'antd/es/locale/zh_CN';
    import * as serviceWorker from './serviceWorker';
    import { ConfigProvider } from 'antd';
    import Route from '@src/router'
    import 'antd/dist/antd.css'
    import { Provider } from 'react-redux'
    import store from '@src/store'
    ReactDOM.render(
      <Provider store={store}>
        <ConfigProvider locale={zh_CN}>
          <Route />
        </ConfigProvider >
      </Provider>,
      document.getElementById('root')
    );
    serviceWorker.unregister();
    入口文件index
    import { configureStore } from '@reduxjs/toolkit';
    import counterSlice from './counterSlice'
    export default configureStore({
      reducer: {
        counter: counterSlice
      },
    });
    store文件index.ts
    import { createSlice } from '@reduxjs/toolkit';
    export const counterSlice = createSlice({
      name: 'counter',
      initialState: {
        value: 0,
      },
      reducers: {
        increment: (state) => {
          state.value += 1;
        },
        decrement: (state) => {
          state.value -= 1;
        },
        incrementAsyncCount: (state, action) => {
          // console.log(action)    =>   {type: "counter/incrementAsyncCount",payload: 1}
          state.value += action.payload;
        },
      },
    });
    export const { increment, decrement, incrementAsyncCount } = counterSlice.actions;
    export const incrementAsync = (num: number) => (dispatch: any) => {
      //可以在这里发送请求,当请求结束之后,再执行reducers
      setTimeout(() => {
        dispatch(incrementAsyncCount(num));
      }, 2000);
    };
    export const selectCount = (state: any) => state.counter.value;
    export default counterSlice.reducer;
    store文件couterSlice.ts
    import React, { useState } from 'react';
    import { useSelector, useDispatch } from 'react-redux';
    import { selectCount, increment, decrement, incrementAsync } from '@src/store/counterSlice';
    import { Button } from 'antd'
    export default () => {
      const count = useSelector(selectCount);
      const dispatch = useDispatch()
      return (
        <div>
          <p>count的值是{count}</p>
          <Button onClick={() => dispatch(increment())}>加1</Button>
          <Button onClick={() => dispatch(decrement())}>减1</Button>
          <Button onClick={() => dispatch(incrementAsync(1))}>延迟2秒加1 </Button>
        </div>
      );
    }
    ReduxTest页面

      

  • 相关阅读:
    推荐一个css抖动库
    八佰
    如何将猫猫监控放在博客上
    一个springboot注解不成功的小问题
    vue整理
    springboot整理
    国外服务器:org.xml.sax.SAXParseException
    记一次tomcat运行起来了但是项目没起来的问题
    一个狗血的mysql编码错误
    js中for(var key in o ){};用法小记
  • 原文地址:https://www.cnblogs.com/minorf/p/12925054.html
Copyright © 2011-2022 走看看