如何在 React 类组件中使用 redux-toolkit createSlice [英] How to use redux-toolkit createSlice with React class components

查看:681
本文介绍了如何在 React 类组件中使用 redux-toolkit createSlice的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

切片器:

export const counterSlice = createSlice({name: '计数器',初始状态:{值:0,},减速器:{增量:状态=>{状态值 += 1;},递减:状态=>{状态值 -= 1;},incrementByAmount: (state, action) =>{state.value += action.payload;},},});

在组件中使用:

const count = useSelector(selectCount);const dispatch = useDispatch();返回 (<按钮className={styles.button}aria-label =增量值";onClick={() =>调度(增量())}>)

我的问题是如何在类组件中使用这个切片器,因为我不能在它们内部使用钩子.我试过使用 connect(来自 redux),但我找不到缝合"的方法.从切片器到我的组件的操作和选择器.我也找不到任何关于此的文档.

解决方案

类 vs. 函数组件和 redux-toolkit vs vanilla"redux 是两个相互独立的决策,互不影响.(不过你应该知道,对于 React 的一切,推荐函数组件和钩子而不是类组件).

<块引用>

我尝试过使用 connect(来自 redux),但找不到缝合"的方法从切片器到我的组件的操作和选择器.

文档如何缝合"?使用 useDispatchuseSelector 时的动作和选择器?这样做,但使用 connect 高阶组件.

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

来自文档:

<块引用>

大多数情况下,您可能希望使用 ES6 解构语法将动作创建器函数提取为变量,也可能需要使用 reducer:

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

const counterSlice = createSlice(/* 与之前相同 */);//从切片中解构动作和减速器(或者您可以作为 counterSlice.actions 访问)const { 动作,reducer } = counterSlice;//导出单个动作创建器函数出口const { 增量,减量, incrementByAmount } = 动作;//通常,reducer 是默认导出,但这并不重要导出默认减速器;

connect 的第一个参数是 mapStateToProps,您可以在其中使用选择器(内联箭头函数 state => state.something 或您导入的选择器函数)来创建来自国家的道具.这可能看起来像:

const mapStateToProps = (state) =>({计数:state.counter.value});

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

从反应"导入反应;从react-redux"导入{连接};从./counterSlice"导入{增量,减量};class MyComponent 扩展了 React.Component {使成为() {返回 (<div><h1>Count 是 {this.props.count}</h1><button onClick={() =>this.props.increment()}>增量<button onClick={() =>this.props.decrement()}>递减

);}}const mapStateToProps = (状态) =>({计数:state.counter.value});const mapDispatchToProps = { 递增,递减 };导出默认连接(mapStateToProps,mapDispatchToProps)(MyComponent);

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

从反应"导入反应;从react-redux"导入{连接};从./counterSlice"导入{增量,减量};class MyComponent 扩展了 React.Component {使成为() {返回 (<div><h1>Count 是 {this.props.count}</h1><button onClick={() =>this.props.dispatch(increment())}>增量<button onClick={() =>this.props.dispatch(decrement())}>递减

);}}const mapStateToProps = (状态) =>({计数:state.counter.value});导出默认连接(mapStateToProps)(MyComponent);

完整的 CodeSandbox

I've started using the redux-toolkit slicers in functional components, (example from react-redux example)

slicer:

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;
    },
  },
});

use in component:

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

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

my question is how can I use this slicer in the class component since I cant use hooks inside them. I've tried using connect (from redux) but I can't find a way to "stitch" the actions and selectors from the slicer to my component. I couldn't find any documentation on this as well.

解决方案

Class vs. function components and redux-toolkit vs "vanilla" redux are two independent decisions that don't have any impact on each other. (Though you should be aware that function components and hooks are recommended over class components for everything React).

I've tried using connect (from redux) but I can't find a way to "stitch" the actions and selectors from the slicer to my component.

How do the docs "stitch" the actions and selectors when using useDispatch and useSelector? Do that, but with the connect higher-order component instead.

The increment() function in the docs example that you posted doesn't just magically exist, it needs to be imported from the slice. You can export the entire actions object and use actions.increment but you usually see the actions exported as individual variables.

From the docs:

Most of the time, you'll probably want to use ES6 destructuring syntax to pull out the action creator functions as variables, and possibly the reducer as well:

Your slice file might look like this:

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;

The first argument of connect is mapStateToProps, where you use selectors (either inline arrow functions state => state.something or selector functions that you import) to create an object of props from the state. That might look like:

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

The second argument mapDispatchToProps is optional. If you pass an object with your action creators, your component will receive versions of those action creators that are already bound to dispatch. You would be able to call this.props.increment() directly rather than this.props.dispatch(increment()). You will see this syntax commonly used in tutorials with 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);

If you leave off the mapDispatchToProps argument entirely, your component receives the raw dispatch function. You would call the dispatch on you imported action creators like this.props.dispatch(increment()). This syntax is more similar to how useDispatch is used. Both connect and useDispatch give you access to the dispatch function and you can call that function with an action that you create from an action creator function like increment() or 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

这篇关于如何在 React 类组件中使用 redux-toolkit createSlice的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆