【问题标题】:Using dispatch in class based component give error of invalid hook call在基于类的组件中使用调度会导致无效的钩子调用错误
【发布时间】:2020-02-12 08:25:01
【问题描述】:

我是react-redux 的新手。我有这个代码,我正在使用reactreduxTypeScript。 在此代码中使用基于类的组件,我想使用 dispatch 调用操作以增加 counter 的值,但是这给了我以下错误。

Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app

这是我基于类的组件代码:

import React from 'react';
import { connect, useDispatch } from 'react-redux';
import { Dispatch } from 'redux';
import { increment, decrement } from '../actions/counterAction';

interface IHome {
    counter: 0
}

class Home extends React.Component<IHome> {
    render() {
        const dispatch = useDispatch();

        return (
            <div>
                This is the home page {this.props.counter}
                <button onClick={()=>dispatch(increment)}>+</button>
                <button>-</button>
            </div>
        );
    }
}

const mapStateToProps = (state: IHome) => {
    return {
        counter: state.counter
    }
}

const mapDispatchToProps = (dispatch: Dispatch) => {
    return {
        increment: () => dispatch(increment()),
        decrement: () => dispatch(decrement())
    }
}

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

我不知道问题出在哪里。

【问题讨论】:

    标签: reactjs typescript redux react-redux


    【解决方案1】:

    useDispatch() 钩子只能在功能组件中使用。

    由于您已经连接了组件,因此您已经通过 props 将 redux 操作(decrementincrement)传递给了您的组件。

    但是,您需要修复组件的 props 接口,目前,TypeScript 认为唯一有效的 prop 是 counter

    interface StoreProps {
      counter: number
    }
    
    interface DispatchProps {
      increment: () => void;
      decrement: () => void;
    }
    
    type IHome = DispatchProps & StoreProps;
    
    class Home extends React.Component<IHome> {
        render() {
            const { counter, increment, decrement } = this.props;
            return (
                <div>
                    This is the home page {counter}
                    <button onClick={()=>increment()}>+</button>
                    <button>-</button>
                </div>
            );
        }
    }
    

    【讨论】:

    • 好的,但是你需要从渲染函数中移除'const dispatch'。否则这将给出相同的结果。
    【解决方案2】:

    Home 是一个类组件。如果要在其中使用钩子,则必须将其更改为功能组件。在这种情况下,您可以摆脱 connect 和 map... 函数调用,并使用 useStore 挂钩来存储。

    export default const Home: React.FC<IHome> = () => {
      const dispatch = useDispatch();
      const store = useStore()
    
      return (
          <div>
              This is the home page {store.getState().counter}
              <button onClick={() => dispatch(increment())}>+</button>
              <button>-</button>
          </div>
      );
    }
    

    【讨论】:

    • 我用过一次 const 并且它工作但我不想像这样传递每个状态'({counter})',这不好,所以我使用 mapStateToProps 然后连接一起,在我的类组件中必须有另一种使用 mapDispatchToProps 函数的方法。
    • 是的@peter,但我想使用类组件而不是 const,如果它不是类组件那么这个答案是正确的,我已经知道了
    猜你喜欢
    • 1970-01-01
    • 2021-11-03
    • 2020-12-21
    • 1970-01-01
    • 2022-01-20
    • 2021-07-25
    • 2022-06-15
    • 1970-01-01
    • 2020-11-29
    相关资源
    最近更新 更多