当使用钩子导出类时,我应该远离类吗?



这是一个基于知识的问题。我是React的新手,来自一个基于Angular TypeScript类的背景。我想在使用React时继续使用TypeScript,但在编译钩子时遇到麻烦。

这段代码来自create-react app库,使用了一个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>
);
}
}

但是当我编译它时-我得到这个非常常见的错误

错误:无效钩子调用。钩子只能在函数体内部调用函数分量的。这可能发生在以下情况之一原因:

  1. 你可能有不匹配的版本的React和渲染器(如React DOM)
  2. 你可能违反了Hooks的规则
  3. 你可能在同一个应用程序中有多个React副本,参见https://reactjs.org/link/invalid-hook-call了解如何调试的提示并解决这个问题。

很明显,我的代码没有坚持任何错误(这一次,很清楚,这让我高兴)。但是,这是否意味着在使用钩子时,我将失去导出默认类语法?

作为上下文,我在父组件(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 />
...

任何信息我都很感激。由于

****** EDIT *******

我看到你可以使用高阶分量如这里所述

如何在React经典的"类"组件中使用React钩子?

这就引出了一个问题,现在使用基于类的语法对React是明智的吗?

额外阅读基于下面的答案:https://www.twilio.com/blog/react-choose-functional-components

恢复到之前的样子,钩子只能在React Function组件中使用。

// Correct, function component
export function Counter() {
// Incorrect, class component
export default class Counter extends React.Component<unknown> {
render(): {

挂线问题是#2,"打破钩的规则"。具体来说,这违反了只从React函数调用钩子(你的第二个例子是React类而不是React函数)。

相关内容

  • 没有找到相关文章

最新更新