The nine best recommendations in the new React docs
https://reactjs.org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous
React may batch multiple setState() calls into a single update for performance.
Or, may not. Described in the context of using a function for setState (applies to hooks too?)
https://reactjs.org/docs/react-component.html#setstate
Think of setState() as a request rather than an immediate command to update the component. For better perceived performance, React may delay it, and then update several components in a single pass. React does not guarantee that the state changes are applied immediately.
setState() does not always immediately update the component. It may batch or defer the update until later. This makes reading this.state right after calling setState() a potential pitfall.
Currently (React 16 and earlier), only updates inside React event handlers are batched by default. There is an unstable API to force batching outside of event handlers for rare cases when you need it.
In future versions (probably React 17 and later), React will batch all updates by default so you won’t have to think about this. As always, we will announce any changes about this on the React blog and in the release notes.
no matter how many setState() calls in how many components you do inside a React event handler, they will produce only a single re-render at the end of the event.
https://reactjs.org/docs/hooks-effect.html
Probably:
Data fetching, setting up a subscription, and manually changing the DOM in React components are all examples of side effects.
So they do explicitly list data fetching, even first here. But it’s not the main consideration in the rest of their docs.
If you’re familiar with React class lifecycle methods, you can think of useEffect Hook as componentDidMount, componentDidUpdate, and componentWillUnmount combined.
But I think I read later you should not think of it as a one-to-one mapping.
In React class components, the render method itself shouldn’t cause side effects. It would be too early — we typically want to perform our effects after React has updated the DOM.
This is not mainly considering network requests.
Instead of thinking in terms of “mounting” and “updating”, you might find it easier to think that effects happen “after render”.
This leads us to ask “which renders do I want this to happen after?”
React guarantees the DOM has been updated by the time it runs the effects.
This is why flicker can happen.
Unlike componentDidMount or componentDidUpdate, effects scheduled with useEffect don’t block the browser from updating the screen.
This is one reason it’s best not to think of it as identical to them.
Earlier, we looked at how to express side effects that don’t require any cleanup. However, some effects do. For example, we might want to set up a subscription to some external data source. In that case, it is important to clean up so that we don’t introduce a memory leak!
Another reason is you might not want to have duplicate things running, like duplicate intervals.
We’ll continue this page with an in-depth look at some aspects of useEffect that experienced React users will likely be curious about. Don’t feel obligated to dig into them now.
Still baffling to me that they don’t consider the dependency array a core part of the API.
This behavior ensures consistency by default and prevents bugs that are common in class components due to missing update logic.
You can tell React to skip applying an effect if certain values haven’t changed between re-renders.
Effects happen on every render, but you can skip some if values haven’t changed.
If you use this optimization, make sure the array includes all values from the component scope (such as props and state) that change over time and that are used by the effect. Otherwise, your code will reference stale values from previous renders.
This is from the mental model of “effects run on every render, skipping them is only a performance optimization.” So it doesn’t directly relate to the approach “I have a requirement to only run this a certain number of times.
If you want to run an effect and clean it up only once (on mount and unmount), you can pass an empty array ([]) as a second argument. This tells React that your effect doesn’t depend on any values from props or state, so it never needs to re-run.
So if you want to tell React “this does depend on values from props or state, but I still don’t want it to re-run when they change”, that is not the React mental model.
While passing [] as the second argument is closer to the familiar componentDidMount and componentWillUnmount mental model, there are usually better solutions to avoid re-running effects too often.
As a last resort, if you want something like this in a class, you can use a ref to hold a mutable variable. Then you can write and read to it.
So a ref is not just for storing DOM elements.
So if you say “I only want this to run once, so I want to pass the empty array, but the eslint rule is making me pass the props I use,” this is not the useEffect mental model. Instead, think:
I wish the useEffect API had been designed differently, but since it’s the React way, it’s better for us to use and learn it in the conventional way, than to do our own thing. And it may be there are benefits to their way that I don’t realize.
Another way to think about it is, the dependency array also indicates what values your effect depends on. If you omit them, that is communicating something incorrect to the reader and to React. That could cause any number of problems in the future.
So, why leave the ESLint rule on when turning it off and specifying no dependencies would work?
CODEOWNERS
file to assign/alert for code reviewpull_request_template.yml
react-ga
react-router-dom
history
module, createBrowserHistory
history.listen()
package.json
- homepage
property--testURL=http://example.tld/myPath
react-router-dom
, history
module, createBrowserHistory
, basename
attributestart
and build
, REACT_APP_VERSION=$npm_package_version
%REACT_APP_VERSION%
in index.html
bundlesize
packagesource-map-explorer
react-helmet
for head tagseslint-plugin-jsx-a11y
@axe-core/react
whitelist
/blacklist
to prevent some transient/secure things from being persisteduseEffect
to check for some data and history.push
if notchildren
(maybe not when need to redirect)useState
to only store the minimal value, not full pixel widthpackage.json
supported it)curly: ['warn', 'all'],
'import/no-anonymous-default-export': 'off',
'import/order': ['warn', {alphabetize: {order: 'asc'}}], // group and then alphabetize lines - https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/order.md
'sort-imports': ['warn', {ignoreDeclarationSort: true, ignoreMemberSort: false}], // alphabetize named imports - https://eslint.org/docs/rules/sort-imports
'jest/no-focused-tests': 'warn',
'jest/no-identical-title': 'warn',
'jest/no-standalone-expect': 'warn',
'jest/no-test-prefixes': 'warn',
'jest/prefer-called-with': 'warn',
'jest/valid-expect-in-promise': 'warn',
// jsx-a11y exceptions/disabling not respected by react-scripts; disable by file instead
'no-duplicate-imports': 'warn', // https://eslint.org/docs/rules/no-duplicate-imports
'no-param-reassign': ['warn', { props: true }],
'no-shadow': 'warn',
'prefer-const': 'warn',
'prettier/prettier': 'warn',
'react/default-props-match-prop-types': 'warn',
'react/jsx-uses-react': 'off', // indicates that a use of JSX counts as using the React import; only needed if no-unused-vars is used; https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-uses-react.md
'react/jsx-key': 'warn',
'react/no-unused-prop-types': 'warn',
'react/prop-types': 'warn',
'react/react-in-jsx-scope': 'off', // requires an explicit React import; https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/react-in-jsx-scope.md
'react/require-default-props': 'warn',
import React from 'react'
was required in any file using JSXreact/jsx-uses-react
and react/react-in-jsx-scope
aren’t needed (and are misleading) and can be turned offdompurify
dangerouslySetInnerHTML