网站搜索

reactjs - 在基于类的组件中使用 dispatch 会报无效 Hook 调用错误


我对 react-redux 是新手。我有这段代码,我正在使用 react、redux 和 TypeScript。在这段代码中使用的是基于类的组件,我想使用 dispatch 来调用 action 以增加 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);

我不知道问题出在哪里。

答案#1

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

既然你已经连接了你的组件,你已经通过 props 将 redux 操作 (decrement 和 increment) 传递给了你的组件。

然而,你需要修复你组件的 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>
        );
    }
}

答案#2

Home 是一个类组件。如果你想在其中使用 hooks,你必须将其改为函数组件。在这种情况下,你可以去掉 connect 和 map... 函数调用,并使用 useStore hook 来获取 store。

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