redux 这么难吗

我是一个多年的Vue的使用者,我经常使用Vue + Vue-Router + Vuex来开发单页面应用,那么当切换到React框架时,这一切都变得不一样了,首先Vue和React之间的区别不是很大,都是用来实现UI的库,Router的区别有一些,到状态管理这边,React有Redux、Mobx等多种解决方案,相比Vue的Vuex来说着实是复杂些,Vuex更加简单容易理解。

今天我们就通过简单易懂大白话的方式来理解Redux究竟是做什么的?

为什么要有Redux

首先React和Vue一样,都是对DOM的一层抽象,并没有像Angular一样提供整套的Web开发解决方案。它们都缺乏代码结构、组件通信方案。而对于大型复杂应用来说,这两点又非常重要,所以只使用Vue和React没办法写大型应用。

为了解决问题,2014年Facebook提供Flux架构的概念,2015年Redux出现,将Flux架构和函数式编程结合,很快成为了前端的热门架构方案。

你可能不需要 Redux

这句话放在Vuex上也是适用的,Redux和Vuex都是解决一类问题而出现的架构方案,我们很多时候并不必须使用它们。

曾经有人说过

“如果你不知道是否需要 Redux,那就是不需要它。”

Redux 的创造者 Dan Abramov 又补充了一句。

“只有遇到 React 实在解决不了的问题,你才需要 Redux 。”

如果UI非常简单,没有过多的交互,我们其实并不需要Redux,使用它反而会增加复杂性

如果我们的多个组件的状态需要被共享、一个组件的状态更改可以使其他组件的状态也被改变,这时我们就需要使用Redux或者其他状态管理工具。

上面我们提到了Flux,如果不明白Flux也没有关系,它不耽误我们理解Redux,如果感兴趣可以去查看文档。

Redux 有很好的文档,当然本文目的是通过简单的方式说明Redux的用处和用法,如果要深入探究还是要去查看文档。

在React中使用Redux

Redux是一个单独的库,如果要将Redux用在React项目中我还需要react-redux这个库,用来将Redux和React进行连接。

我们要先来安装下面的依赖:

npm i @reduxjs/toolkit react-redux

假设我们要用Redux来实现一个计数器,创建counterSlice.js用来管理计数器的状态:

import {
    
     createSlice } from '@reduxjs/toolkit';

export const slice = createSlice({
    
    
  name: 'counter',
  initialState: {
    
    
    value: 0,
  },
  reducers: {
    
    
    increment: state => {
    
    
      state.value += 1;
    },
    decrement: state => {
    
    
      state.value -= 1;
    },
    incrementByAmount: (state, action) => {
    
    
      state.value += action.payload;
    },
  },
});

export const {
    
     increment, decrement, incrementByAmount } = slice.actions;

export const incrementAsync = amount => dispatch => {
    
    
  setTimeout(() => {
    
    
    dispatch(incrementByAmount(amount));
  }, 1000);
};

export const selectCount = state => state.counter.value;

export default slice.reducer;

然后创建store.js,引入我们刚才创建的计数器模块,然后创建出计数器store

import {
    
     configureStore } from '@reduxjs/toolkit';
import counterReducer from '../features/counter/counterSlice';

export default configureStore({
    
    
  reducer: {
    
    
    counter: counterReducer,
  },
});

然后在index.js中引入store并使用Provider组件注入

import App from './App';
import store from './app/store';
import { Provider } from 'react-redux';

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

之后就是在组件或者页面中去获取和操作store中的状态数据

import React, { useState } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import {
  decrement,
  increment,
  incrementByAmount,
  incrementAsync,
  selectCount,
} from './counterSlice';
import styles from './Counter.module.css';

export function Counter() {
  const count = useSelector(selectCount);
  const dispatch = useDispatch();
  const [incrementAmount, setIncrementAmount] = useState('2');

  return (
    <div>
      <div className={styles.row}>
        <button
          className={styles.button}
          aria-label="Increment value"
          onClick={() => dispatch(increment())}
        >
          +
        </button>
        <span className={styles.value}>{count}</span>
        <button
          className={styles.button}
          aria-label="Decrement value"
          onClick={() => dispatch(decrement())}
        >
          -
        </button>
      </div>
      <div className={styles.row}>
        <input
          className={styles.textbox}
          aria-label="Set increment amount"
          value={incrementAmount}
          onChange={e => setIncrementAmount(e.target.value)}
        />
        <button
          className={styles.button}
          onClick={() =>
            dispatch(incrementByAmount(Number(incrementAmount) || 0))
          }
        >
          Add Amount
        </button>
        <button
          className={styles.asyncButton}
          onClick={() => dispatch(incrementAsync(Number(incrementAmount) || 0))}
        >
          Add Async
        </button>
      </div>
    </div>
  );
}
  • 使用useSelector方法找到我们想要的状态数据
  • 使用useDispatch()来触发我们对状态的操作

完整的例子请看:https://codesandbox.io/s/github/reduxjs/redux-essentials-counter-example/tree/master/?from-embed

最后

一起学习更多前端知识,微信搜索【小帅的编程笔记】,每天更新

おすすめ

転載: blog.csdn.net/cmdfas/article/details/121345889
おすすめ