react-redux 入门学习笔记

Redux 思想

刚开始接触 Redux 时,我认为这仅仅是一个管理 state 的小工具。我想象了一个巨大的 component,它的 state 异常繁杂,数组套数组,对象套对象。这时 redux 把编码焦点从 state 上转移,只重视 action,如:在 todolist 的最后加上"写作业"一项,只需 dispatch 一个{ type: “ADD_TODO”, text: “写作业”}的 action 就够了,避免直接和 state 打交道。

更深入一些后,我了解到 Redux 可以解决“全局状态”问题。状态提升究竟繁琐了,对于一些 state,不知道哪个边缘的小组件突然要用到它,而这将会带来一场很大的变动。

随后,“时间旅行”这一样例给我带来了不小的惊讶,不止是能看到当前的 state,每一次 state 的变更都被记录以备查验,且随时可以跳转到任意时刻的 state 中。这背后当然是不可变更新思想起了作用,不是直接更新 state,而是更新副本。

install

    npm install @reduxjs/toolkit react-redux

create Redux Store

src/app/store.js

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

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

使用 Provider 将整个 React 组件树包裹起来

将 <Provider> 放置在 index 的顶层包裹,使得整个组件树都在其中。store 是刚才定义的 configureStore。<Provider> 组件使 Redux store 可供任何嵌套组件使用。

src/index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import store from './app/store';
import { Provider } from 'react-redux';

// As of React 18
const root = ReactDOM.createRoot(document.getElementById('root'));

root.render(
  <Provider store={store}>
    <App />
  </Provider>
);

创建 redux state slice

“slice”是应用程序中单个功能的 Redux reducer 逻辑和操作的集合,通常在单个文件中一起定义。该名称来自于将根 Redux 状态对象拆分为多个 state “切片”。

features/counter/counterSlice.js

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

export const counterSlice = createSlice({
  name: 'counter',
  initialState: {
    value: 0,
  },
  reducers: {
    increment: (state) => {
      // 这里看似是直接修改了 state,事实上背后进行了不可变更新
      state.value += 1;
    },
    decrement: (state) => {
      state.value -= 1;
    },
    incrementByAmount: (state, action) => {
      state.value += action.payload;
    },
  },
});

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

export default counterSlice.reducer;

在具体的 React 组件中使用 store 的数据

useSelector 从 store 的 state 中读取一个值并订阅更新,而 useDispatch 返回 store 的 dispatch 方法来让你 dispatch action。

import React 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();

  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>
  );
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值