如何将 redux-toolkit createSlice 与 React 类组件一起使用

Posted

技术标签:

【中文标题】如何将 redux-toolkit createSlice 与 React 类组件一起使用【英文标题】:How to use redux-toolkit createSlice with React class components 【发布时间】:2021-05-22 10:46:48 【问题描述】:

我已经开始在功能组件中使用 redux-toolkit 切片器,(示例来自 react-redux 示例)

切片器:

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

在组件中使用:

const count = useSelector(selectCount);
const dispatch = useDispatch();

return (
  <button
    className=styles.button
    aria-label="Increment value"
    onClick=() => dispatch(increment())
  >
)

我的问题是如何在类组件中使用这个切片器,因为我不能在其中使用钩子。 我尝试过使用连接(来自redux),但我找不到将切片器中的动作和选择器“缝合”到我的组件的方法。 我也找不到这方面的任何文档。

【问题讨论】:

connect HoC (not hook) 早于 hooks,你可以在这里找到信息 - react-redux.js.org/api/connect 【参考方案1】:

类与函数组件以及 redux-toolkit 与“vanilla”redux 是两个独立的决策,彼此之间没有任何影响。 (尽管您应该知道,对于所有 React,建议使用函数组件和钩子而不是类组件)。

我尝试过使用 connect(来自 redux),但我找不到将切片器中的动作和选择器“缝合”到我的组件的方法。

在使用useDispatchuseSelector 时,文档如何“缝合”操作和选择器?这样做,但使用 connect 高阶组件。

您发布的文档示例中的increment() 函数不仅神奇地存在,还需要从切片中导入。您可以导出整个 actions 对象并使用 actions.increment,但您通常会看到导出为单个变量的操作。

来自the docs:

大多数时候,您可能希望使用 ES6 解构语法将 action creator 函数作为变量提取,也可能是 reducer:

您的切片文件可能如下所示:

const counterSlice = createSlice( /* same as before */ );

// destructure actions and reducer from the slice (or you can access as counterSlice.actions)
const  actions, reducer  = counterSlice;

// export individual action creator functions
export const  increment, decrement, incrementByAmount  = actions;

// often the reducer is a default export, but that doesn't matter
export default reducer;

connect 的第一个参数是mapStateToProps,您可以在其中使用选择器(内联箭头函数state =&gt; state.something 或您导入的选择器函数)从状态中创建道具对象。这可能看起来像:

const mapStateToProps = (state) => (
  count: state.counter.value
);

第二个参数mapDispatchToProps 是可选的。如果你将一个对象传递给你的动作创建者,你的组件将收到那些已经绑定到dispatch 的动作创建者的版本。您可以直接拨打this.props.increment() 而不是this.props.dispatch(increment())。你会看到这个语法在教程中常用connect

import React from "react";
import  connect  from "react-redux";
import  increment, decrement  from "./counterSlice";

class MyComponent extends React.Component 
  render() 
    return (
      <div>
        <h1>Count is this.props.count</h1>
        <button onClick=() => this.props.increment()>
          Increment
        </button>
        <button onClick=() => this.props.decrement()>
          Decrement
        </button>
      </div>
    );
  


const mapStateToProps = (state) => (
  count: state.counter.value
);

const mapDispatchToProps =  increment, decrement ;

export default connect(mapStateToProps, mapDispatchToProps)(MyComponent);

如果您完全不使用 mapDispatchToProps 参数,您的组件将接收原始的 dispatch 函数。你可以调用你导入的动作创建者的调度,比如this.props.dispatch(increment())。这种语法更类似于useDispatch 的使用方式。 connectuseDispatch 都允许您访问 dispatch 函数,您可以使用从动作创建函数(如 increment()decrement())创建的动作调用该函数。

import React from "react";
import  connect  from "react-redux";
import  increment, decrement  from "./counterSlice";

class MyComponent extends React.Component 
  render() 
    return (
      <div>
        <h1>Count is this.props.count</h1>
        <button onClick=() => this.props.dispatch(increment())>
          Increment
        </button>
        <button onClick=() => this.props.dispatch(decrement())>
          Decrement
        </button>
      </div>
    );
  


const mapStateToProps = (state) => (
  count: state.counter.value
);

export default connect(mapStateToProps)(MyComponent);

Complete CodeSandbox

【讨论】:

以上是关于如何将 redux-toolkit createSlice 与 React 类组件一起使用的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Storybook 中使用 redux-toolkit?

如何在 Redux-toolkit 中使用两个不同的切片?

如何实现redux-toolkit和next,js又不丢s-s-r

将项目添加到 redux-toolkit 中的嵌套数组

如何使用 redux-toolkit 中的 createSlice 方法在不同的 reducer 函数中使用单个动作类型

从 Redux-Toolkit 存储中获取返回 undefined