@ -36,6 +36,8 @@ Code linters find problems in your code as you write, helping you fix them early
* [Install ESLint with the recommended configuration for React](https://www.npmjs.com/package/eslint-config-react-app) (be sure you have [Node installed!](https://nodejs.org/en/download/current/))
* [Integrate ESLint in VSCode with the official extension](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint)
**Make sure that you've enabled all the [`eslint-plugin-react-hooks`](https://www.npmjs.com/package/eslint-plugin-react-hooks) rules for your project.** They are essential and catch the most severe bugs early. The recommended [`eslint-config-react-app`](https://www.npmjs.com/package/eslint-config-react-app) preset already includes them.
### Formatting {/*formatting*/}
The last thing you want to do when sharing your code with another contributor is get into an discussion about [tabs vs spaces](https://www.google.com/search?q=tabs+vs+spaces)! Fortunately, [Prettier](https://prettier.io/) will clean up your code by reformatting it to conform to preset, configurable rules. Run Prettier, and all your tabs will be converted to spaces—and your indentation, quotes, etc will also all be changed to conform to the configuration. In the ideal setup, Prettier will run when you save your file, quickly making these edits for you.
@ -126,7 +126,7 @@ Either `'./Gallery.js'` or `'./Gallery'` will work with React, though the former
</Note>
<DeepDivetitle="Default vs Named Exports">
<DeepDivetitle="Default vs named exports">
There are two primary ways to export values with JavaScript: default exports and named exports. So far, our examples have only used default exports. But you can use one or both of them in the same file. **A file can have no more than one _default_ export, but it can have as many _named_ exports as you like.**
@ -284,7 +284,7 @@ When `Accordion`'s `activeIndex` state changes to `1`, the second `Panel` receiv
</DiagramGroup>
<DeepDivetitle="Controlled and Uncontrolled Components">
<DeepDivetitle="Controlled and uncontrolled components">
It is common to call a component with some local state "uncontrolled". For example, the original `Panel` component with an `isActive` state variable is uncontrolled because its parent cannot influence whether the panel is active or not.
@ -475,13 +475,15 @@ function SearchBar() {
function List({ items }) {
return (
<table>
{items.map(food => (
<trkey={food.id}>
<td>{food.name}</td>
<td>{food.description}</td>
</tr>
))}
<table>
<tbody>
{items.map(food => (
<trkey={food.id}>
<td>{food.name}</td>
<td>{food.description}</td>
</tr>
))}
</tbody>
</table>
);
}
@ -566,13 +568,15 @@ function SearchBar({ query, onChange }) {
@ -1325,7 +1325,7 @@ Here is a small form that is supposed to let the user leave some feedback. When
<Hint>
Are there any limitations on _where_ Hooks may be called? Does this component break any rules?
Are there any limitations on _where_ Hooks may be called? Does this component break any rules? Check if there are any comments disabling the linter checks--this is where the bugs often hide!
</Hint>
@ -1339,6 +1339,7 @@ export default function FeedbackForm() {
if (isSent) {
return <h1>Thank you!</h1>;
} else {
// eslint-disable-next-line
const [message, setMessage] = useState('');
return (
<formonSubmit={e=> {
@ -1363,7 +1364,9 @@ export default function FeedbackForm() {
<Solution>
Hooks can only be called at the top level of the component function. Here, the first `isSent` definition follows this rule, but the `message` definition is nested in a condition. Move it out of the condition to fix the issue:
Hooks can only be called at the top level of the component function. Here, the first `isSent` definition follows this rule, but the `message` definition is nested in a condition.
Move it out of the condition to fix the issue:
<Sandpack>
@ -1437,7 +1440,7 @@ export default function FeedbackForm() {
Try moving the second `useState` call after the `if` condition and notice how this breaks it again.
In general, these types of mistakes are caught by the [`eslint-plugin-react-hooks`](https://www.npmjs.com/package/eslint-plugin-react-hooks) linter rule. If you don't see an error when you try the faulty code locally, you need to set it up in your build tooling configuration.
If your linter is [configured for React](/learn/editor-setup#linting), you should see a lint error when you make a mistake like this. If you don't see an error when you try the faulty code locally, you need to set up linting for your project.
Notice that editing the form doesn't work yet. There is a console error in the sandbox above explaining why:
<ConsoleBlocklevel="error">
You provided a \`value\` prop to a form field without an \`onChange\` handler. This will render a read-only field.
</ConsoleBlock>
In the sandbox above, `ProductTable` and `SearchBar` read the `filterText` and `inStockOnly` props to render the table, the input, and the checkbox. For example, here is how `SearchBar` populates the input value:
```js {1,6}
@ -447,8 +455,8 @@ function SearchBar({ filterText, inStockOnly }) {
placeholder="Search..."/>
```
However, you haven't added any code to respond to the user actions like typing yet. This wil be your final step.
Refer to the [Managing State](/learn/managing-state) to dive deeper into how React uses state and how you can organize your app with it.
## Step 5: Add inverse data flow {/*step-5-add-inverse-data-flow*/}
@ -60,7 +60,7 @@ Each React component is a JavaScript function that may contain some markup that
<Note>
[JSX and React are two separate things](https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html#whats-a-jsx-transform) you _can_ use independently of each other.
JSX and React are two separate things. They're often used together, but you *can* [use them independently](https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html#whats-a-jsx-transform) of each other. JSX is a syntax extension, while React is a JavaScript library.
@ -176,7 +176,7 @@ Components are regular JavaScript functions, so you can keep multiple components
Because the `Profile` components are rendered inside `Gallery`—even several times!—we can say that `Gallery` is a **parent component,** rendering each `Profile` as a "child". This is part of the magic of React: you can define a component once, and then use it in as many places and as many times as you like.
<DeepDivetitle="Components All the Way Down">
<DeepDivetitle="Components all the way down">
Your React application begins at a "root" component. Usually, it is created automatically when you start a new project. For example, if you use [CodeSandbox](https://codesandbox.io/) or [Create React App](https://create-react-app.dev/), the root component is defined in `src/App.js`. If you use the framework [Next.js](https://nextjs.org/), the root component is defined in `pages/index.js`. In these examples, you've been exporting root components.