reactjs - Bør jeg gå bort fra klasser når jeg bruker eksportklasser med hooks?
Dette er et kunnskapsbasert spørsmål. Jeg er ny på React og kommer fra en Angular TypeScript-klassebasert bakgrunn. Jeg ønsker å fortsette å bruke TypeScript når jeg bruker React, men har problemer med å kompilere hooks.
Denne koden er fra create-react app-biblioteket og bruker en Redux-mal. Den bruker en tellerkomponent for å vise en teller.
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>
);
}
Dette fungerer som forventet, så jeg endret det til dette
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>
);
}
}
Men når jeg kompilerer det - får jeg denne veldig vanlige feilen
Feil: Ugyldig hook-kall. Hooks kan kun kalles inne i kroppen til en funksjonskomponent. Dette kan skje av en av følgende grunner:
- Du kan ha ulike versjoner av React og renderer (for eksempel React DOM)
- Du kan bryte Regler for Hooks
- Du kan ha mer enn én kopi av React i samme app. Se https://reactjs.org/link/invalid-hook-call for tips om hvordan du kan feilsøke og fikse dette problemet.
Ganske åpenbart følger ikke koden min noen av feilene (som for en gangs skyld er ganske tydelig, noe som gleder meg). Men betyr dette at når jeg bruker hooks, vil jeg nå miste eksport default class-syntaksen?
For kontekst, jeg brukte denne koden i min overordnede komponent (App) og den kompilerer.
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 />
...
All informasjon jeg ville være takknemlig for. Takk
****** REDIGER *******
Jeg ser at du kan bruke High Order Components som forklart her
Hvordan kan jeg bruke React hooks i en tradisjonell React-`class`-komponent?
noe som stiller spørsmålet, er det klokt å bruke klassebasert syntaks for React nå?
Ytterligere lesing basert på svaret nedenfor: https://www.twilio.com/blog/react-choose-functional-components
Svar #1
Gjenopprett det du hadde før, hooks kan kun brukes inne i React-funksjonskomponenter.
// Correct, function component
export function Counter() {
// Incorrect, class component
export default class Counter extends React.Component<unknown> {
render(): {
Linting-problemet er #2, "breaking the Rules of Hooks". Spesifikt bryter dette reglene om kun å kalle Hooks fra React-funksjoner (ditt andre eksempel er en React-klasse, ikke en React-funksjon).
