这是一个基于知识的问题。我是 React 的新手,来自基于 Angular TypeScript 类的背景。我想在使用 React 时继续使用 TypeScript,但在编译 hook 时遇到问题。
此代码来自 create-react 应用程序库并使用 Redux 模板。它使用计数器组件来显示计数器。
import React, { useState } from 'react';
import { useAppSelector, useAppDispatch } from '../../app/hooks';
import {
decrement,
increment,
incrementByAmount,
incrementAsync,
incrementIfOdd,
selectCount,
} from './counterSlice';
import styles from './Counter.module.css';
export function Counter() {
const count = useAppSelector(selectCount);
const dispatch = useAppDispatch();
const [incrementAmount, setIncrementAmount] = useState('2');
const incrementValue = Number(incrementAmount) || 0;
return (
<div>
<div className={styles.row}>
<button
className={styles.button}
aria-label="Decrement value"
onClick={() => dispatch(decrement())}
>
-
</button>
<span className={styles.value}>{count}</span>
<button
className={styles.button}
aria-label="Increment value"
onClick={() => dispatch(increment())}
>
+
</button>
</div>
<div className={styles.row}>
<input
className={styles.textbox}
aria-label="Set increment amount"
value={incrementAmount}
onChange={(e) => setIncrementAmount(e.target.value)}
/>
<button
className={styles.button}
onClick={() => dispatch(incrementByAmount(incrementValue))}
>
Add Amount
</button>
<button
className={styles.asyncButton}
onClick={() => dispatch(incrementAsync(incrementValue))}
>
Add Async
</button>
<button
className={styles.button}
onClick={() => dispatch(incrementIfOdd(incrementValue))}
>
Add If Odd
</button>
</div>
</div>
);
}
这按预期工作,所以我将其更改为
export default class Counter extends React.Component<unknown> {
render(): {
const count = useAppSelector(selectCount);
const dispatch = useAppDispatch();
const [incrementAmount, setIncrementAmount] = useState('2');
const incrementValue = Number(incrementAmount) || 0;
return (
<div>
<div className={styles.row}>
<button
className={styles.button}
aria-label="Decrement value"
onClick={() => dispatch(decrement())}
>
-
</button>
<span className={styles.value}>{count}</span>
<button
className={styles.button}
aria-label="Increment value"
onClick={() => dispatch(increment())}
>
+
</button>
</div>
<div className={styles.row}>
<input
className={styles.textbox}
aria-label="Set increment amount"
value={incrementAmount}
onChange={(e) => setIncrementAmount(e.target.value)}
/>
<button
className={styles.button}
onClick={() => dispatch(incrementByAmount(incrementValue))}
>
Add Amount
</button>
<button
className={styles.asyncButton}
onClick={() => dispatch(incrementAsync(incrementValue))}
>
Add Async
</button>
<button
className={styles.button}
onClick={() => dispatch(incrementIfOdd(incrementValue))}
>
Add If Odd
</button>
</div>
</div>
);
}
}
但是当我编译它时 - 我得到了这个非常常见的错误
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:
- You might have mismatching versions of React and the renderer (such as React DOM)
- You might be breaking the Rules of Hooks
- You might have more than one copy of React in the same app See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.
很明显,我的代码没有遵循任何错误(这一次,我很清楚哪个让我满意)。但这是否意味着在使用钩子(Hook)时,我现在将丢失导出默认类语法?
对于上下文,我在我的父组件 (App) 中使用了这段代码,它确实可以编译。
import React from 'react';
import './App.css';
import Counter from './features/counter/Counter';
export default class App extends React.Component<unknown> {
render() {
return (
<div className="App">
<header className="App-header">
<Counter />
...
如有任何信息,我将不胜感激。谢谢
****** 编辑 *******
我看到您可以按照此处的说明使用高阶组件
How can I use React hooks in React classic `class` component?
这引出了一个问题,现在为 React 使用基于类的语法是否明智?
基于以下答案的补充阅读:https://www.twilio.com/blog/react-choose-functional-components
最佳答案
恢复到以前的状态,钩子(Hook)只能在 React Function 组件中使用。
// Correct, function component
export function Counter() {
// Incorrect, class component
export default class Counter extends React.Component<unknown> {
render(): {
linting 问题是 #2,“打破 Hooks 规则”。具体来说,这违反了 Only Call Hooks from React Functions (您的第二个示例是 React 类而不是 React 函数)。
关于reactjs - 在使用带有钩子(Hook)的导出类时,我应该远离类吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69379800/