diff --git a/content/community/conferences.md b/content/community/conferences.md index e138b119a..ea8613c78 100644 --- a/content/community/conferences.md +++ b/content/community/conferences.md @@ -57,6 +57,11 @@ July 15-21, 2019. New York City, USA [Website](https://reactweek.nyc) - [Twitter](https://twitter.com/ReactWeek) +### React Rally 2019 +August 22-23, 2019. Salt Lake City, USA. + +[Website](https://www.reactrally.com/) - [Twitter](https://twitter.com/ReactRally) - [Instagram](https://www.instagram.com/reactrally/) + ### ComponentsConf 2019 {#componentsconf-2019} September 6, 2019 in Melbourne, Australia [Website](https://www.componentsconf.com.au/) - [Twitter](https://twitter.com/componentsconf) diff --git a/content/docs/hooks-faq.md b/content/docs/hooks-faq.md index fc404e0c2..7d311366e 100644 --- a/content/docs/hooks-faq.md +++ b/content/docs/hooks-faq.md @@ -18,6 +18,7 @@ prev: hooks-reference.html ).join('\n') --> +<<<<<<< HEAD * [Внедрение хуков](#adoption-strategy) * [В какой версии React появились хуки?](#which-versions-of-react-include-hooks) * [Нужно ли переписать все мои классовые компоненты?](#do-i-need-to-rewrite-all-my-class-components) @@ -61,6 +62,52 @@ prev: hooks-reference.html ### В какой версии React появились хуки? {#which-versions-of-react-include-hooks} Начиная с релиза 16.8.0, React включает в себя стабильную реализацию хуков для: +======= +* **[Adoption Strategy](#adoption-strategy)** + * [Which versions of React include Hooks?](#which-versions-of-react-include-hooks) + * [Do I need to rewrite all my class components?](#do-i-need-to-rewrite-all-my-class-components) + * [What can I do with Hooks that I couldn't with classes?](#what-can-i-do-with-hooks-that-i-couldnt-with-classes) + * [How much of my React knowledge stays relevant?](#how-much-of-my-react-knowledge-stays-relevant) + * [Should I use Hooks, classes, or a mix of both?](#should-i-use-hooks-classes-or-a-mix-of-both) + * [Do Hooks cover all use cases for classes?](#do-hooks-cover-all-use-cases-for-classes) + * [Do Hooks replace render props and higher-order components?](#do-hooks-replace-render-props-and-higher-order-components) + * [What do Hooks mean for popular APIs like Redux connect() and React Router?](#what-do-hooks-mean-for-popular-apis-like-redux-connect-and-react-router) + * [Do Hooks work with static typing?](#do-hooks-work-with-static-typing) + * [How to test components that use Hooks?](#how-to-test-components-that-use-hooks) + * [What exactly do the lint rules enforce?](#what-exactly-do-the-lint-rules-enforce) +* **[From Classes to Hooks](#from-classes-to-hooks)** + * [How do lifecycle methods correspond to Hooks?](#how-do-lifecycle-methods-correspond-to-hooks) + * [How can I do data fetching with Hooks?](#how-can-i-do-data-fetching-with-hooks) + * [Is there something like instance variables?](#is-there-something-like-instance-variables) + * [Should I use one or many state variables?](#should-i-use-one-or-many-state-variables) + * [Can I run an effect only on updates?](#can-i-run-an-effect-only-on-updates) + * [How to get the previous props or state?](#how-to-get-the-previous-props-or-state) + * [Why am I seeing stale props or state inside my function?](#why-am-i-seeing-stale-props-or-state-inside-my-function) + * [How do I implement getDerivedStateFromProps?](#how-do-i-implement-getderivedstatefromprops) + * [Is there something like forceUpdate?](#is-there-something-like-forceupdate) + * [Can I make a ref to a function component?](#can-i-make-a-ref-to-a-function-component) + * [How can I measure a DOM node?](#how-can-i-measure-a-dom-node) + * [What does const [thing, setThing] = useState() mean?](#what-does-const-thing-setthing--usestate-mean) +* **[Performance Optimizations](#performance-optimizations)** + * [Can I skip an effect on updates?](#can-i-skip-an-effect-on-updates) + * [Is it safe to omit functions from the list of dependencies?](#is-it-safe-to-omit-functions-from-the-list-of-dependencies) + * [What can I do if my effect dependencies change too often?](#what-can-i-do-if-my-effect-dependencies-change-too-often) + * [How do I implement shouldComponentUpdate?](#how-do-i-implement-shouldcomponentupdate) + * [How to memoize calculations?](#how-to-memoize-calculations) + * [How to create expensive objects lazily?](#how-to-create-expensive-objects-lazily) + * [Are Hooks slow because of creating functions in render?](#are-hooks-slow-because-of-creating-functions-in-render) + * [How to avoid passing callbacks down?](#how-to-avoid-passing-callbacks-down) + * [How to read an often-changing value from useCallback?](#how-to-read-an-often-changing-value-from-usecallback) +* **[Under the Hood](#under-the-hood)** + * [How does React associate Hook calls with components?](#how-does-react-associate-hook-calls-with-components) + * [What is the prior art for Hooks?](#what-is-the-prior-art-for-hooks) + +## Adoption Strategy {#adoption-strategy} + +### Which versions of React include Hooks? {#which-versions-of-react-include-hooks} + +Starting with 16.8.0, React includes a stable implementation of React Hooks for: +>>>>>>> b1bc193dbad464f7c659b10f3f57e37e265a063e * React DOM * React DOM Server @@ -454,7 +501,65 @@ function ScrollView({row}) { Несмотря на то, что вам не понадобится это часто, вы можете предоставить некоторые императивные методы родительскому компоненту, используя хук [`useImperativeHandle`](/docs/hooks-reference.html#useimperativehandle). +<<<<<<< HEAD ### Что значит `const [thing, setThing] = useState()`? {#what-does-const-thing-setthing--usestate-mean} +======= +### How can I measure a DOM node? {#how-can-i-measure-a-dom-node} + +In order to measure the position or size of a DOM node, you can use a [callback ref](/docs/refs-and-the-dom.html#callback-refs). React will call that callback whenever the ref gets attached to a different node. Here is a [small demo](https://codesandbox.io/s/l7m0v5x4v9): + +```js{4-8,12} +function MeasureExample() { + const [height, setHeight] = useState(0); + + const measuredRef = useCallback(node => { + if (node !== null) { + setHeight(node.getBoundingClientRect().height); + } + }, []); + + return ( + <> +

Hello, world

+

The above header is {Math.round(height)}px tall

+ + ); +} +``` + +We didn't choose `useRef` in this example because an object ref doesn't notify us about *changes* to the current ref value. Using a callback ref ensures that [even if a child component displays the measured node later](https://codesandbox.io/s/818zzk8m78) (e.g. in response to a click), we still get notified about it in the parent component and can update the measurements. + +Note that we pass `[]` as a dependency array to `useCallback`. This ensures that our ref callback doesn't change between the re-renders, and so React won't call it unnecessarily. + +If you want, you can [extract this logic](https://codesandbox.io/s/m5o42082xy) into a reusable Hook: + +```js{2} +function MeasureExample() { + const [rect, ref] = useClientRect(); + return ( + <> +

Hello, world

+ {rect !== null && +

The above header is {Math.round(rect.height)}px tall

+ } + + ); +} + +function useClientRect() { + const [rect, setRect] = useState(null); + const ref = useCallback(node => { + if (node !== null) { + setRect(node.getBoundingClientRect()); + } + }, []); + return [rect, ref]; +} +``` + + +### What does `const [thing, setThing] = useState()` mean? {#what-does-const-thing-setthing--usestate-mean} +>>>>>>> b1bc193dbad464f7c659b10f3f57e37e265a063e Если вы не знакомы с этим синтаксисом, ознакомьтесь с [объяснением](/docs/hooks-state.html#tip-what-do-square-brackets-mean) в документации хука состояния. @@ -857,8 +962,13 @@ function Form() { const [text, updateText] = useState(''); const textRef = useRef(); +<<<<<<< HEAD useLayoutEffect(() => { textRef.current = text; // Записать в реф +======= + useEffect(() => { + textRef.current = text; // Write it to the ref +>>>>>>> b1bc193dbad464f7c659b10f3f57e37e265a063e }); const handleSubmit = useCallback(() => { @@ -898,7 +1008,7 @@ function useEventCallback(fn, dependencies) { throw new Error('Невозможно вызвать обработчик события во время рендера.'); }); - useLayoutEffect(() => { + useEffect(() => { ref.current = fn; }, [fn, ...dependencies]); diff --git a/content/docs/hooks-reference.md b/content/docs/hooks-reference.md index 1029e0646..1a6120d39 100644 --- a/content/docs/hooks-reference.md +++ b/content/docs/hooks-reference.md @@ -96,6 +96,8 @@ const [state, setState] = useState(() => { Если вы обновите состояние хука тем же значением, что и текущее состояние, React досрочно выйдет из хука без повторного рендера дочерних элементов и запуска эффектов. (React использует [алгоритм сравнения `Object.is`](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Object/is#Description).) +Note that React may still need to render that specific component again before bailing out. That shouldn't be a concern because React won't unnecessarily go "deeper" into the tree. If you're doing expensive calculations while rendering, you can optimize them with `useMemo`. + ### `useEffect` {#useeffect} ```js @@ -171,12 +173,32 @@ useEffect( ### `useContext` {#usecontext} ```js -const context = useContext(Context); +const value = useContext(MyContext); ``` +<<<<<<< HEAD Принимает объект контекста (значение, возвращённое из `React.createContext`) и возвращает текущее значение контекста, как указано ближайшим поставщиком контекста для данного контекста. Когда провайдер обновляется, этот хук инициирует повторный рендер с последним значением контекста. +======= +Accepts a context object (the value returned from `React.createContext`) and returns the current context value for that context. The current context value is determined by the `value` prop of the nearest `` above the calling component in the tree. + +When the nearest `` above the component updates, this Hook will trigger a rerender with the latest context `value` passed to that `MyContext` provider. + +Don't forget that the argument to `useContext` must be the *context object itself*: + + * **Correct:** `useContext(MyContext)` + * **Incorrect:** `useContext(MyContext.Consumer)` + * **Incorrect:** `useContext(MyContext.Provider)` + +A component calling `useContext` will always re-render when the context value changes. If re-rendering the component is expensive, you can [optimize it by using memoization](https://github.com/facebook/react/issues/15156#issuecomment-474590693). + +>Tip +> +>If you're familiar with the context API before Hooks, `useContext(MyContext)` is equivalent to `static contextType = MyContext` in a class, or to ``. +> +>`useContext(MyContext)` only lets you *read* the context and subscribe to its changes. You still need a `` above in the tree to *provide* the value for this context. +>>>>>>> b1bc193dbad464f7c659b10f3f57e37e265a063e ## Дополнительные хуки {#additional-hooks} @@ -283,6 +305,8 @@ function Counter({initialCount}) { Если вы вернёте то же значение из редюсера хука, что и текущее состояние, React выйдет без перерисовки дочерних элементов или запуска эффектов. (React использует [алгоритм сравнения Object.is](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Object/is#Description).) +Note that React may still need to render that specific component again before bailing out. That shouldn't be a concern because React won't unnecessarily go "deeper" into the tree. If you're doing expensive calculations while rendering, you can optimize them with `useMemo`. + ### `useCallback` {#usecallback} ```js @@ -354,7 +378,20 @@ function TextInputWithFocusButton() { } ``` +<<<<<<< HEAD Обратите внимание, что `useRef()` полезен не только для атрибута `ref`. Он также [удобен для хранения любого изменяемого значения](/docs/hooks-faq.html#is-there-something-like-instance-variables) примерно так же, как вы используете поля экземпляров в классах. +======= +Essentially, `useRef` is like a "box" that can hold a mutable value in its `.current` property. + +You might be familiar with refs primarily as a way to [access the DOM](/docs/refs-and-the-dom.html). If you pass a ref object to React with `
`, React will set its `.current` property to the corresponding DOM node whenever that node changes. + +However, `useRef()` is useful for more than the `ref` attribute. It's [handy for keeping any mutable value around](/docs/hooks-faq.html#is-there-something-like-instance-variables) similar to how you'd use instance fields in classes. + +This works because `useRef()` creates a plain JavaScript object. The only difference between `useRef()` and creating a `{current: ...}` object yourself is that `useRef` will give you the same ref object on every render. + +Keep in mind that `useRef` *doesn't* notify you when its content changes. Mutating the `.current` property doesn't cause a re-render. If you want to run some code when React attaches or detaches a ref to a DOM node, you may want to use a [callback ref](/docs/hooks-faq.html#how-can-i-measure-a-dom-node) instead. + +>>>>>>> b1bc193dbad464f7c659b10f3f57e37e265a063e ### `useImperativeHandle` {#useimperativehandle} @@ -387,7 +424,15 @@ FancyInput = forwardRef(FancyInput); > Совет > +<<<<<<< HEAD > Если вы переносите код из классового компонента, `useLayoutEffect` запускается в той же фазе, что и `componentDidMount` и `componentDidUpdate`, поэтому, если вы не уверены, какой хук эффект использовать, это, вероятно, наименее рискованно. +======= +> If you're migrating code from a class component, note `useLayoutEffect` fires in the same phase as `componentDidMount` and `componentDidUpdate`. However, **we recommend starting with `useEffect` first** and only trying `useLayoutEffect` if that causes a problem. +> +>If you use server rendering, keep in mind that *neither* `useLayoutEffect` nor `useEffect` can run until the JavaScript is downloaded. This is why React warns when a server-rendered component contains `useLayoutEffect`. To fix this, either move that logic to `useEffect` (if it isn't necessary for the first render), or delay showing that component until after the client renders (if the HTML looks broken until `useLayoutEffect` runs). +> +>To exclude a component that needs layout effects from the server-rendered HTML, render it conditionally with `showChild && ` and defer showing it with `useEffect(() => { setShowChild(true); }, [])`. This way, the UI doesn't appear broken before hydration. +>>>>>>> b1bc193dbad464f7c659b10f3f57e37e265a063e ### `useDebugValue` {#usedebugvalue}