diff --git a/.babelrc b/.babelrc
deleted file mode 100644
index 40f742563..000000000
--- a/.babelrc
+++ /dev/null
@@ -1,41 +0,0 @@
-{
- "presets": [
- [
- "@babel/preset-env",
- {
- "loose": true,
- "modules": false,
- "useBuiltIns": "usage",
- "shippedProposals": true,
- "targets": {
- "browsers": [">0.25%", "not dead"],
- }
- }
- ],
- [
- "@babel/preset-react",
- {
- "useBuiltIns": true,
- "pragma": "React.createElement",
- }
- ],
- "@babel/flow"
- ],
- "plugins": [
- [
- "@babel/plugin-proposal-class-properties",
- {
- "loose": true
- }
- ],
- "@babel/plugin-syntax-dynamic-import",
- "babel-plugin-macros",
- [
- "@babel/plugin-transform-runtime",
- {
- "helpers": true,
- "regenerator": true
- }
- ]
- ]
-}
\ No newline at end of file
diff --git a/.circleci/config.yml b/.circleci/config.yml
deleted file mode 100644
index 028250472..000000000
--- a/.circleci/config.yml
+++ /dev/null
@@ -1,20 +0,0 @@
-version: 2
-jobs:
- build:
- docker:
- - image: circleci/node:12
- steps:
- - checkout
- - restore_cache:
- keys:
- - dependencies-{{ checksum "yarn.lock" }}
- - run:
- name: Install
- command: yarn install --pure-lockfile
- - save_cache:
- paths:
- - node_modules
- key: dependencies-{{ checksum "yarn.lock" }}
- - run:
- name: Check Prettier, ESLint, Flow
- command: yarn ci-check
diff --git a/.env.development b/.env.development
new file mode 100644
index 000000000..a692f21c7
--- /dev/null
+++ b/.env.development
@@ -0,0 +1 @@
+SANDPACK_BARE_COMPONENTS=true
\ No newline at end of file
diff --git a/.env.production b/.env.production
new file mode 100644
index 000000000..445c9c4d0
--- /dev/null
+++ b/.env.production
@@ -0,0 +1,2 @@
+NEXT_PUBLIC_GA_TRACKING_ID = 'UA-41298772-4'
+SANDPACK_BARE_COMPONENTS=true
\ No newline at end of file
diff --git a/.eslintignore b/.eslintignore
index 942541715..4738cb697 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -1,10 +1,3 @@
-node_modules/*
-
-# Ignore markdown files and examples
-content/*
-
-# Ignore built files
-public/*
-
-# Ignore examples
-examples/*
\ No newline at end of file
+scripts
+plugins
+next.config.js
diff --git a/.eslintrc b/.eslintrc
index a51454ef2..147e54607 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -1,18 +1,16 @@
{
- "extends": [
- "fbjs"
- ],
- "plugins": [
- "prettier",
- "react"
- ],
- "parser": "babel-eslint",
+ "root": true,
+ "extends": "next/core-web-vitals",
+ "parser": "@typescript-eslint/parser",
+ "plugins": ["@typescript-eslint"],
"rules": {
- "relay/graphql-naming": 0,
- "max-len": 0
+ "no-unused-vars": "off",
+ "@typescript-eslint/no-unused-vars": "warn"
},
"env": {
"node": true,
- "browser": true
+ "commonjs": true,
+ "browser": true,
+ "es6": true
}
}
diff --git a/.flowconfig b/.flowconfig
deleted file mode 100644
index 836f6ec1e..000000000
--- a/.flowconfig
+++ /dev/null
@@ -1,35 +0,0 @@
-[ignore]
-
-/content/.*
-/node_modules/.*
-/public/.*
-
-[include]
-
-[libs]
-./node_modules/fbjs/flow/lib/dev.js
-./flow
-
-[options]
-module.system=haste
-module.system.node.resolve_dirname=node_modules
-module.system.node.resolve_dirname=src
-
-esproposal.class_static_fields=enable
-esproposal.class_instance_fields=enable
-unsafe.enable_getters_and_setters=true
-
-munge_underscores=false
-
-suppress_type=$FlowIssue
-suppress_type=$FlowFixMe
-suppress_type=$FixMe
-suppress_type=$FlowExpectedError
-
-suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(3[0-3]\\|[1-2][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*www[a-z,_]*\\)?)\\)
-suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(3[0-3]\\|[1-2][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*www[a-z,_]*\\)?)\\)?:? #[0-9]+
-suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
-suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError
-
-[version]
-^0.56.0
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index d3c569401..7e4f6d2f2 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -1,12 +1,10 @@
-
-
"
+
+ - name: Create Comment
+ uses: peter-evans/create-or-update-comment@v1.4.4
+ if: success() && steps.fc.outputs.comment-id == 0
+ with:
+ issue-number: ${{ steps.get-comment-body.outputs.pr-number }}
+ body: ${{ steps.get-comment-body.outputs.body }}
+
+ - name: Update Comment
+ uses: peter-evans/create-or-update-comment@v1.4.4
+ if: success() && steps.fc.outputs.comment-id != 0
+ with:
+ issue-number: ${{ steps.get-comment-body.outputs.pr-number }}
+ body: ${{ steps.get-comment-body.outputs.body }}
+ comment-id: ${{ steps.fc.outputs.comment-id }}
+ edit-mode: replace
diff --git a/.github/workflows/site_lint.yml b/.github/workflows/site_lint.yml
new file mode 100644
index 000000000..bf446393a
--- /dev/null
+++ b/.github/workflows/site_lint.yml
@@ -0,0 +1,27 @@
+name: Site Lint / Heading ID check
+
+on:
+ push:
+ branches:
+ - main # change this if your default branch is named differently
+ pull_request:
+ types: [opened, synchronize, reopened]
+
+jobs:
+ lint:
+ runs-on: ubuntu-latest
+
+ name: Lint on node 12.x and ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v1
+ - name: Use Node.js 12.x
+ uses: actions/setup-node@v1
+ with:
+ node-version: 12.x
+
+ - name: Install deps and build (with cache)
+ uses: bahmutov/npm-install@v1.7.10
+
+ - name: Lint codebase
+ run: yarn ci-check
diff --git a/.gitignore b/.gitignore
index d1bde99ce..d8bec488b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,38 @@
-.cache
-.DS_STORE
-.idea
-node_modules
-public
-yarn-error.log
\ No newline at end of file
+# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
+
+# dependencies
+/node_modules
+/.pnp
+.pnp.js
+
+# testing
+/coverage
+
+# next.js
+/.next/
+/out/
+
+# production
+/build
+
+# misc
+.DS_Store
+*.pem
+tsconfig.tsbuildinfo
+
+# debug
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+
+# local env files
+.env.local
+.env.development.local
+.env.test.local
+.env.production.local
+
+# vercel
+.vercel
+
+# external fonts
+public/fonts/**/Optimistic_*.woff2
diff --git a/.husky/pre-commit b/.husky/pre-commit
new file mode 100755
index 000000000..dc0378c34
--- /dev/null
+++ b/.husky/pre-commit
@@ -0,0 +1,4 @@
+#!/bin/sh
+. "$(dirname "$0")/_/husky.sh"
+
+yarn lint-staged
\ No newline at end of file
diff --git a/.nvmrc b/.nvmrc
deleted file mode 100644
index 66df3b7ab..000000000
--- a/.nvmrc
+++ /dev/null
@@ -1 +0,0 @@
-12.16.1
diff --git a/.prettierignore b/.prettierignore
new file mode 100644
index 000000000..96f1f96d2
--- /dev/null
+++ b/.prettierignore
@@ -0,0 +1 @@
+src/content/**/*.md
diff --git a/.prettierrc b/.prettierrc
index eb91e6abb..19b54ad05 100644
--- a/.prettierrc
+++ b/.prettierrc
@@ -1,8 +1,21 @@
{
"bracketSpacing": false,
- "jsxBracketSameLine": true,
- "parser": "flow",
- "printWidth": 80,
"singleQuote": true,
- "trailingComma": "all"
-}
\ No newline at end of file
+ "bracketSameLine": true,
+ "trailingComma": "es5",
+ "printWidth": 80,
+ "overrides": [
+ {
+ "files": "*.css",
+ "options": {
+ "parser": "css"
+ }
+ },
+ {
+ "files": "*.md",
+ "options": {
+ "parser": "mdx"
+ }
+ }
+ ]
+}
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index e10f4f53e..0e861af35 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -18,19 +18,9 @@ This is a [good summary](https://medium.com/@kvosswinkel/coding-like-a-journalis
The documentation is divided into sections to cater to different learning styles and use cases. When editing an article, try to match the surrounding text in tone and style. When creating a new article, try to match the tone of the other articles in the same section. Learn about the motivation behind each section below.
-**[Installation](https://reactjs.org/docs/getting-started.html)** gives an overview of the docs, and demonstrates two different ways to use it: either as a simple `
-
-## CoffeeScript integration {#coffeescript-integration}
-
-[Vjeux](http://blog.vjeux.com/) used the fact that JSX is just a syntactic sugar on-top of regular JS to rewrite the React front-page examples in CoffeeScript.
-
-> Multiple people asked what's the story about JSX and CoffeeScript. There is no JSX pre-processor for CoffeeScript and I'm not aware of anyone working on it. Fortunately, CoffeeScript is pretty expressive and we can play around the syntax to come up with something that is usable.
->
-> ```javascript
-> {div, h3, textarea} = React.DOM
-> (div {className: 'MarkdownEditor'}, [
-> (h3 {}, 'Input'),
-> (textarea {onKeyUp: @handleKeyUp, ref: 'textarea'},
-> @state.value
-> )
-> ])
-> ```
->
-> [Read the full post...](http://blog.vjeux.com/2013/javascript/react-coffeescript.html)
-
-## Tutorial in Plain JavaScript {#tutorial-in-plain-javascript}
-
-We've seen a lot of people comparing React with various frameworks. [Ricardo Tomasi](http://ricardo.cc/) decided to re-implement the tutorial without any framework, just plain JavaScript.
-
-> Facebook & Instagram launched the React framework and an accompanying tutorial. Developer Vlad Yazhbin decided to rewrite that using AngularJS. The end result is pretty neat, but if you're like me you will not actually appreciate the HTML speaking for itself and doing all the hard work. So let's see what that looks like in plain javascript.
->
-> [Read the full post...](http://ricardo.cc/2013/06/07/react-tutorial-rewritten-in-plain-javascript.html)
diff --git a/content/blog/2013-07-02-react-v0-4-autobind-by-default.md b/content/blog/2013-07-02-react-v0-4-autobind-by-default.md
deleted file mode 100644
index 9c98fd9b2..000000000
--- a/content/blog/2013-07-02-react-v0-4-autobind-by-default.md
+++ /dev/null
@@ -1,51 +0,0 @@
----
-title: "New in React v0.4: Autobind by Default"
-author: [zpao]
----
-
-React v0.4 is very close to completion. As we finish it off, we'd like to share with you some of the major changes we've made since v0.3. This is the first of several posts we'll be making over the next week.
-
-
-## What is React.autoBind? {#what-is-reactautobind}
-
-If you take a look at most of our current examples, you'll see us using `React.autoBind` for event handlers. This is used in place of `Function.prototype.bind`. Remember that in JS, [function calls are late-bound](https://bonsaiden.github.io/JavaScript-Garden/#function.this). That means that if you simply pass a function around, the `this` used inside won't necessarily be the `this` you expect. `Function.prototype.bind` creates a new, properly bound, function so that when called, `this` is exactly what you expect it to be.
-
-Before we launched React, we would write this:
-
-```js{4}
-React.createClass({
- onClick: function(event) {/* do something with this */},
- render: function() {
- return ;
- }
-});
-```
-
-We wrote `React.autoBind` as a way to cache the function creation and save on memory usage. Since `render` can get called multiple times, if you used `this.onClick.bind(this)` you would actually create a new function on each pass. With React v0.3 you were able to write this instead:
-
-```js{2,4}
-React.createClass({
- onClick: React.autoBind(function(event) {/* do something with this */}),
- render: function() {
- return ;
- }
-});
-```
-
-
-## What's Changing in v0.4? {#whats-changing-in-v04}
-
-After using `React.autoBind` for a few weeks, we realized that there were very few times that we didn't want that behavior. So we made it the default! Now all methods defined within `React.createClass` will already be bound to the correct instance.
-
-Starting with v0.4 you can just write this:
-
-```js{2,4}
-React.createClass({
- onClick: function(event) {/* do something with this */},
- render: function() {
- return ;
- }
-});
-```
-
-For v0.4 we will simply be making `React.autoBind` a no-op — it will just return the function you pass to it. Most likely you won't have to change your code to account for this change, though we encourage you to update. We'll publish a migration guide documenting this and other changes that come along with React v0.4.
diff --git a/content/blog/2013-07-03-community-roundup-4.md b/content/blog/2013-07-03-community-roundup-4.md
deleted file mode 100644
index b7bd158c2..000000000
--- a/content/blog/2013-07-03-community-roundup-4.md
+++ /dev/null
@@ -1,58 +0,0 @@
----
-title: "Community Round-up #4"
-author: [vjeux]
----
-
-React reconciliation process appears to be very well suited to implement a text editor with a live preview as people at Khan Academy show us.
-
-## Khan Academy {#khan-academy}
-
-[Ben Kamens](http://bjk5.com/) explains how [Sophie Alpert](http://sophiebits.com/) and [Joel Burget](http://joelburget.com/) are promoting React inside of [Khan Academy](https://www.khanacademy.org/). They now have three projects in the works using React.
-
-> Recently two Khan Academy devs dropped into our team chat and said they were gonna use React to write a new feature. They even hinted that we may want to adopt it product-wide.
->
-> "The library is only a week old. It's a brand new way of thinking about things. We're the first to use it outside of Facebook. Heck, even the React devs were surprised to hear we're using this in production!!!"
->
-> [Read the full post...](http://bjk5.com/post/53742233351/getting-your-team-to-adopt-new-technology)
-
-The best part is the demo of how React reconciliation process makes live editing more user-friendly.
-
-> Our renderer, post-React, is on the left. A typical math editor's preview is on the right.
-
-[](http://bjk5.com/post/53742233351/getting-your-team-to-adopt-new-technology)
-
-## React Snippets {#react-snippets}
-
-Over the past several weeks, members of our team, [Pete Hunt](http://www.petehunt.net/) and [Paul O'Shannessy](http://zpao.com/), answered many questions that were asked in the [React group](https://groups.google.com/forum/#!forum/reactjs). They give a good overview of how to integrate React with other libraries and APIs through the use of [Mixins](/docs/reusable-components.html) and [Lifecycle Methods](/docs/working-with-the-browser.html).
-
-> [Listening Scroll Event](https://groups.google.com/forum/#!topic/reactjs/l6PnP8qbofk)
->
-> * [JSFiddle](http://jsfiddle.net/aabeL/1/): Basically I've given you two mixins. The first lets you react to global scroll events. The second is, IMO, much more useful: it gives you scroll start and scroll end events, which you can use with setState() to create components that react based on whether the user is scrolling or not.
->
-> [Fade-in Transition](https://groups.google.com/forum/#!topic/reactjs/RVAY_eQmdpo)
->
-> * [JSFiddle](http://jsfiddle.net/ufe8k/1/): Creating a new `` component and using jQuery `.fadeIn()` function on the DOM node.
-> * [JSFiddle](http://jsfiddle.net/R8f5L/5/): Using CSS transition instead.
->
-> [Socket.IO Integration](https://groups.google.com/forum/#!topic/reactjs/pyUZBRWcHB4)
->
-> * [Gist](https://gist.github.com/zpao/5686416): The big thing to notice is that my component is pretty dumb (it doesn't have to be but that's how I chose to model it). All it does is render itself based on the props that are passed in. renderOrUpdate is where the "magic" happens.
-> * [Gist](https://gist.github.com/petehunt/5687230): This example is doing everything -- including the IO -- inside of a single React component.
-> * [Gist](https://gist.github.com/petehunt/5687276): One pattern that we use at Instagram a lot is to employ separation of concerns and consolidate I/O and state into components higher in the hierarchy to keep the rest of the components mostly stateless and purely display.
->
-> [Sortable jQuery Plugin Integration](https://groups.google.com/forum/#!topic/reactjs/mHfBGI3Qwz4)
->
-> * [JSFiddle](http://jsfiddle.net/LQxy7/): Your React component simply render empty divs, and then in componentDidMount() you call React.renderComponent() on each of those divs to set up a new root React tree. Be sure to explicitly unmountAndReleaseReactRootNode() for each component in componentWillUnmount().
-
-## Introduction to React Screencast {#introduction-to-react-screencast}
-
-[Pete Hunt](http://www.petehunt.net/) recorded himself implementing a simple `
- );
-}
-```
-
-**[Try it on CodeSandbox](https://codesandbox.io/s/brave-villani-ypxvf)**
-
-Notice how when you type into the input, the `` component suspends, and we see the `
Loading...
` fallback until we get fresh results. This is not ideal. It would be better if we could see the *previous* translation for a bit while we're fetching the next one.
-
-In fact, if we open the console, we'll see a warning:
-
-```
-Warning: App triggered a user-blocking update that suspended.
-
-The fix is to split the update into multiple parts: a user-blocking update to provide immediate feedback, and another update that triggers the bulk of the changes.
-
-Refer to the documentation for useTransition to learn how to implement this pattern.
-```
-
-As we mentioned earlier, if some state update causes a component to suspend, that state update should be wrapped in a transition. Let's add `useTransition` to our component:
-
-```js{4-6,10,13}
-function App() {
- const [query, setQuery] = useState(initialQuery);
- const [resource, setResource] = useState(initialResource);
- const [startTransition, isPending] = useTransition({
- timeoutMs: 5000
- });
-
- function handleChange(e) {
- const value = e.target.value;
- startTransition(() => {
- setQuery(value);
- setResource(fetchTranslation(value));
- });
- }
-
- // ...
-
-}
-```
-
-**[Try it on CodeSandbox](https://codesandbox.io/s/zen-keldysh-rifos)**
-
-Try typing into the input now. Something's wrong! The input is updating very slowly.
-
-We've fixed the first problem (suspending outside of a transition). But now because of the transition, our state doesn't update immediately, and it can't "drive" a controlled input!
-
-The answer to this problem **is to split the state in two parts:** a "high priority" part that updates immediately, and a "low priority" part that may wait for a transition.
-
-In our example, we already have two state variables. The input text is in `query`, and we read the translation from `resource`. We want changes to the `query` state to happen immediately, but changes to the `resource` (i.e. fetching a new translation) should trigger a transition.
-
-So the correct fix is to put `setQuery` (which doesn't suspend) *outside* the transition, but `setResource` (which will suspend) *inside* of it.
-
-```js{4,5}
-function handleChange(e) {
- const value = e.target.value;
-
- // Outside the transition (urgent)
- setQuery(value);
-
- startTransition(() => {
- // Inside the transition (may be delayed)
- setResource(fetchTranslation(value));
- });
-}
-```
-
-**[Try it on CodeSandbox](https://codesandbox.io/s/lively-smoke-fdf93)**
-
-With this change, it works as expected. We can type into the input immediately, and the translation later "catches up" to what we have typed.
-
-### Deferring a Value {#deferring-a-value}
-
-By default, React always renders a consistent UI. Consider code like this:
-
-```js
-<>
-
-
->
-```
-
-React guarantees that whenever we look at these components on the screen, they will reflect data from the same `user`. If a different `user` is passed down because of a state update, you would see them changing together. You can't ever record a screen and find a frame where they would show values from different `user`s. (If you ever run into a case like this, file a bug!)
-
-This makes sense in the vast majority of situations. Inconsistent UI is confusing and can mislead users. (For example, it would be terrible if a messenger's Send button and the conversation picker pane "disagreed" about which thread is currently selected.)
-
-However, sometimes it might be helpful to intentionally introduce an inconsistency. We could do it manually by "splitting" the state like above, but React also offers a built-in Hook for this:
-
-```js
-import { useDeferredValue } from 'react';
-
-const deferredValue = useDeferredValue(value, {
- timeoutMs: 5000
-});
-```
-
-To demonstrate this feature, we'll use [the profile switcher example](https://codesandbox.io/s/musing-ramanujan-bgw2o). Click the "Next" button and notice how it takes 1 second to do a transition.
-
-Let's say that fetching the user details is very fast and only takes 300 milliseconds. Currently, we're waiting a whole second because we need both user details and posts to display a consistent profile page. But what if we want to show the details faster?
-
-If we're willing to sacrifice consistency, we could **pass potentially stale data to the components that delay our transition**. That's what `useDeferredValue()` lets us do:
-
-```js{2-4,10,11,21}
-function ProfilePage({ resource }) {
- const deferredResource = useDeferredValue(resource, {
- timeoutMs: 1000
- });
- return (
- Loading profile...}>
-
- Loading posts...}>
-
-
-
- );
-}
-
-function ProfileTimeline({ isStale, resource }) {
- const posts = resource.posts.read();
- return (
-
- {posts.map(post => (
-
{post.text}
- ))}
-
- );
-}
-```
-
-**[Try it on CodeSandbox](https://codesandbox.io/s/vigorous-keller-3ed2b)**
-
-The tradeoff we're making here is that `` will be inconsistent with other components and potentially show an older item. Click "Next" a few times, and you'll notice it. But thanks to that, we were able to cut down the transition time from 1000ms to 300ms.
-
-Whether or not it's an appropriate tradeoff depends on the situation. But it's a handy tool, especially when the content doesn't change noticeably between items, and the user might not even realize they were looking at a stale version for a second.
-
-It's worth noting that `useDeferredValue` is not *only* useful for data fetching. It also helps when an expensive component tree causes an interaction (e.g. typing in an input) to be sluggish. Just like we can "defer" a value that takes too long to fetch (and show its old value despite other components updating), we can do this with trees that take too long to render.
-
-For example, consider a filterable list like this:
-
-```js
-function App() {
- const [text, setText] = useState("hello");
-
- function handleChange(e) {
- setText(e.target.value);
- }
-
- return (
-
-
- ...
-
-
- );
-}
-```
-
-**[Try it on CodeSandbox](https://codesandbox.io/s/pensive-shirley-wkp46)**
-
-In this example, **every item in `` has an artificial slowdown -- each of them blocks the thread for a few milliseconds**. We'd never do this in a real app, but this helps us simulate what can happen in a deep component tree with no single obvious place to optimize.
-
-We can see how typing in the input causes stutter. Now let's add `useDeferredValue`:
-
-```js{3-5,18}
-function App() {
- const [text, setText] = useState("hello");
- const deferredText = useDeferredValue(text, {
- timeoutMs: 5000
- });
-
- function handleChange(e) {
- setText(e.target.value);
- }
-
- return (
-
-
- ...
-
-
- );
-}
-```
-
-**[Try it on CodeSandbox](https://codesandbox.io/s/infallible-dewdney-9fkv9)**
-
-Now typing has a lot less stutter -- although we pay for this by showing the results with a lag.
-
-How is this different from debouncing? Our example has a fixed artificial delay (3ms for every one of 80 items), so there is always a delay, no matter how fast our computer is. However, the `useDeferredValue` value only "lags behind" if the rendering takes a while. There is no minimal lag imposed by React. With a more realistic workload, you can expect the lag to adjust to the user’s device. On fast machines, the lag would be smaller or non-existent, and on slow machines, it would be more noticeable. In both cases, the app would remain responsive. That’s the advantage of this mechanism over debouncing or throttling, which always impose a minimal delay and can't avoid blocking the thread while rendering.
-
-Even though there is an improvement in responsiveness, this example isn't as compelling yet because Concurrent Mode is missing some crucial optimizations for this use case. Still, it is interesting to see that features like `useDeferredValue` (or `useTransition`) are useful regardless of whether we're waiting for network or for computational work to finish.
-
-### SuspenseList {#suspenselist}
-
-`` is the last pattern that's related to orchestrating loading states.
-
-Consider this example:
-
-```js{5-10}
-function ProfilePage({ resource }) {
- return (
- <>
-
- Loading posts...}>
-
-
- Loading fun facts...}>
-
-
- >
- );
-}
-```
-
-**[Try it on CodeSandbox](https://codesandbox.io/s/proud-tree-exg5t)**
-
-The API call duration in this example is randomized. If you keep refreshing it, you will notice that sometimes the posts arrive first, and sometimes the "fun facts" arrive first.
-
-This presents a problem. If the response for fun facts arrives first, we'll see the fun facts below the `
Loading posts...
` fallback for posts. We might start reading them, but then the *posts* response will come back, and shift all the facts down. This is jarring.
-
-One way we could fix it is by putting them both in a single boundary:
-
-```js
-Loading posts and fun facts...}>
-
-
-
-```
-
-**[Try it on CodeSandbox](https://codesandbox.io/s/currying-violet-5jsiy)**
-
-The problem with this is that now we *always* wait for both of them to be fetched. However, if it's the *posts* that came back first, there's no reason to delay showing them. When fun facts load later, they won't shift the layout because they're already below the posts.
-
-Other approaches to this, such as composing Promises in a special way, are increasingly difficult to pull off when the loading states are located in different components down the tree.
-
-To solve this, we will import `SuspenseList`:
-
-```js
-import { SuspenseList } from 'react';
-```
-
-`` coordinates the "reveal order" of the closest `` nodes below it:
-
-```js{3,11}
-function ProfilePage({ resource }) {
- return (
-
-
- Loading posts...}>
-
-
- Loading fun facts...}>
-
-
-
- );
-}
-```
-
-**[Try it on CodeSandbox](https://codesandbox.io/s/black-wind-byilt)**
-
-The `revealOrder="forwards"` option means that the closest `` nodes inside this list **will only "reveal" their content in the order they appear in the tree -- even if the data for them arrives in a different order**. `` has other interesting modes: try changing `"forwards"` to `"backwards"` or `"together"` and see what happens.
-
-You can control how many loading states are visible at once with the `tail` prop. If we specify `tail="collapsed"`, we'll see *at most one* fallback at a time. You can play with it [here](https://codesandbox.io/s/adoring-almeida-1zzjh).
-
-Keep in mind that `` is composable, like anything in React. For example, you can create a grid by putting several `` rows inside a `` table.
-
-## Next Steps {#next-steps}
-
-Concurrent Mode offers a powerful UI programming model and a set of new composable primitives to help you orchestrate delightful user experiences.
-
-It's a result of several years of research and development, but it's not finished. In the section on [adopting Concurrent Mode](/docs/concurrent-mode-adoption.html), we'll describe how you can try it and what you can expect.
diff --git a/content/docs/concurrent-mode-reference.md b/content/docs/concurrent-mode-reference.md
deleted file mode 100644
index 663af1b3b..000000000
--- a/content/docs/concurrent-mode-reference.md
+++ /dev/null
@@ -1,214 +0,0 @@
----
-id: concurrent-mode-reference
-title: Concurrent Mode API Reference (Experimental)
-permalink: docs/concurrent-mode-reference.html
-prev: concurrent-mode-adoption.html
----
-
-
-
-
-
->Caution:
->
->This page describes **experimental features that are [not yet available](/docs/concurrent-mode-adoption.html) in a stable release**. Don't rely on experimental builds of React in production apps. These features may change significantly and without a warning before they become a part of React.
->
->This documentation is aimed at early adopters and people who are curious. **If you're new to React, don't worry about these features** -- you don't need to learn them right now.
-
-
-
-This page is an API reference for the React [Concurrent Mode](/docs/concurrent-mode-intro.html). If you're looking for a guided introduction instead, check out [Concurrent UI Patterns](/docs/concurrent-mode-patterns.html).
-
-**Note: This is a Community Preview and not the final stable version. There will likely be future changes to these APIs. Use at your own risk!**
-
-- [Enabling Concurrent Mode](#concurrent-mode)
- - [`createRoot`](#createroot)
- - [`createBlockingRoot`](#createblockingroot)
-- [Suspense](#suspense)
- - [`Suspense`](#suspensecomponent)
- - [`SuspenseList`](#suspenselist)
- - [`useTransition`](#usetransition)
- - [`useDeferredValue`](#usedeferredvalue)
-
-## Enabling Concurrent Mode {#concurrent-mode}
-
-### `createRoot` {#createroot}
-
-```js
-ReactDOM.createRoot(rootNode).render();
-```
-
-Replaces `ReactDOM.render(, rootNode)` and enables Concurrent Mode.
-
-For more information on Concurrent Mode, check out the [Concurrent Mode documentation.](/docs/concurrent-mode-intro.html)
-
-### `createBlockingRoot` {#createblockingroot}
-
-```js
-ReactDOM.createBlockingRoot(rootNode).render()
-```
-
-Replaces `ReactDOM.render(, rootNode)` and enables [Blocking Mode](/docs/concurrent-mode-adoption.html#migration-step-blocking-mode).
-
-Opting into Concurrent Mode introduces semantic changes to how React works. This means that you can't use Concurrent Mode in just a few components. Because of this, some apps may not be able to migrate directly to Concurrent Mode.
-
-Blocking Mode only contains a small subset of Concurrent Mode features and is intended as an intermediary migration step for apps that are unable to migrate directly.
-
-## Suspense API {#suspense}
-
-### `Suspense` {#suspensecomponent}
-
-```js
-Loading...}>
-
-
-
-```
-
-`Suspense` lets your components "wait" for something before they can render, showing a fallback while waiting.
-
-In this example, `ProfileDetails` is waiting for an asynchronous API call to fetch some data. While we wait for `ProfileDetails` and `ProfilePhoto`, we will show the `Loading...` fallback instead. It is important to note that until all children inside `` has loaded, we will continue to show the fallback.
-
-`Suspense` takes two props:
-* **fallback** takes a loading indicator. The fallback is shown until all of the children of the `Suspense` component have finished rendering.
-* **unstable_avoidThisFallback** takes a boolean. It tells React whether to "skip" revealing this boundary during the initial load. This API will likely be removed in a future release.
-
-### `` {#suspenselist}
-
-```js
-
-
-
-
-
-
-
-
-
-
- ...
-
-```
-
-`SuspenseList` helps coordinate many components that can suspend by orchestrating the order in which these components are revealed to the user.
-
-When multiple components need to fetch data, this data may arrive in an unpredictable order. However, if you wrap these items in a `SuspenseList`, React will not show an item in the list until previous items have been displayed (this behavior is adjustable).
-
-`SuspenseList` takes two props:
-* **revealOrder (forwards, backwards, together)** defines the order in which the `SuspenseList` children should be revealed.
- * `together` reveals *all* of them when they're ready instead of one by one.
-* **tail (collapsed, hidden)** dictates how unloaded items in a `SuspenseList` is shown.
- * By default, `SuspenseList` will show all fallbacks in the list.
- * `collapsed` shows only the next fallback in the list.
- * `hidden` doesn't show any unloaded items.
-
-Note that `SuspenseList` only operates on the closest `Suspense` and `SuspenseList` components below it. It does not search for boundaries deeper than one level. However, it is possible to nest multiple `SuspenseList` components in each other to build grids.
-
-### `useTransition` {#usetransition}
-
-```js
-const SUSPENSE_CONFIG = { timeoutMs: 2000 };
-
-const [startTransition, isPending] = useTransition(SUSPENSE_CONFIG);
-```
-
-`useTransition` allows components to avoid undesirable loading states by waiting for content to load before **transitioning to the next screen**. It also allows components to defer slower, data fetching updates until subsequent renders so that more crucial updates can be rendered immediately.
-
-The `useTransition` hook returns two values in an array.
-* `startTransition` is a function that takes a callback. We can use it to tell React which state we want to defer.
-* `isPending` is a boolean. It's React's way of informing us whether we're waiting for the transition to finish.
-
-**If some state update causes a component to suspend, that state update should be wrapped in a transition.**
-
-```js
-const SUSPENSE_CONFIG = { timeoutMs: 2000 };
-
-function App() {
- const [resource, setResource] = useState(initialResource);
- const [startTransition, isPending] = useTransition(SUSPENSE_CONFIG);
- return (
- <>
-
- {isPending ? " Loading..." : null}
- }>
-
-
- >
- );
-}
-```
-
-In this code, we've wrapped our data fetching with `startTransition`. This allows us to start fetching the profile data right away, while deferring the render of the next profile page and its associated `Spinner` for 2 seconds (the time shown in `timeoutMs`).
-
-The `isPending` boolean lets React know that our component is transitioning, so we are able to let the user know this by showing some loading text on the previous profile page.
-
-**For an in-depth look at transitions, you can read [Concurrent UI Patterns](/docs/concurrent-mode-patterns.html#transitions).**
-
-#### useTransition Config {#usetransition-config}
-
-```js
-const SUSPENSE_CONFIG = { timeoutMs: 2000 };
-```
-
-`useTransition` accepts an **optional Suspense Config** with a `timeoutMs`. This timeout (in milliseconds) tells React how long to wait before showing the next state (the new Profile Page in the above example).
-
-**Note: We recommend that you share Suspense Config between different modules.**
-
-
-### `useDeferredValue` {#usedeferredvalue}
-
-```js
-const deferredValue = useDeferredValue(value, { timeoutMs: 2000 });
-```
-
-Returns a deferred version of the value that may "lag behind" it for at most `timeoutMs`.
-
-This is commonly used to keep the interface responsive when you have something that renders immediately based on user input and something that needs to wait for a data fetch.
-
-A good example of this is a text input.
-
-```js
-function App() {
- const [text, setText] = useState("hello");
- const deferredText = useDeferredValue(text, { timeoutMs: 2000 });
-
- return (
-
- {/* Keep passing the current text to the input */}
-
- ...
- {/* But the list is allowed to "lag behind" when necessary */}
-
-
- );
- }
-```
-
-This allows us to start showing the new text for the `input` immediately, which allows the webpage to feel responsive. Meanwhile, `MySlowList` "lags behind" for up to 2 seconds according to the `timeoutMs` before updating, allowing it to render with the current text in the background.
-
-**For an in-depth look at deferring values, you can read [Concurrent UI Patterns](/docs/concurrent-mode-patterns.html#deferring-a-value).**
-
-#### useDeferredValue Config {#usedeferredvalue-config}
-
-```js
-const SUSPENSE_CONFIG = { timeoutMs: 2000 };
-```
-
-`useDeferredValue` accepts an **optional Suspense Config** with a `timeoutMs`. This timeout (in milliseconds) tells React how long the deferred value is allowed to lag behind.
-
-React will always try to use a shorter lag when network and device allows it.
diff --git a/content/docs/concurrent-mode-suspense.md b/content/docs/concurrent-mode-suspense.md
deleted file mode 100644
index 12ad112b2..000000000
--- a/content/docs/concurrent-mode-suspense.md
+++ /dev/null
@@ -1,736 +0,0 @@
----
-id: concurrent-mode-suspense
-title: Suspense for Data Fetching (Experimental)
-permalink: docs/concurrent-mode-suspense.html
-prev: concurrent-mode-intro.html
-next: concurrent-mode-patterns.html
----
-
-
-
-
-
->Caution:
->
->This page describes **experimental features that are [not yet available](/docs/concurrent-mode-adoption.html) in a stable release**. Don't rely on experimental builds of React in production apps. These features may change significantly and without a warning before they become a part of React.
->
->This documentation is aimed at early adopters and people who are curious. **If you're new to React, don't worry about these features** -- you don't need to learn them right now. For example, if you're looking for a data fetching tutorial that works today, read [this article](https://www.robinwieruch.de/react-hooks-fetch-data/) instead.
-
-
-
-React 16.6 added a `` component that lets you "wait" for some code to load and declaratively specify a loading state (like a spinner) while we're waiting:
-
-```jsx
-const ProfilePage = React.lazy(() => import('./ProfilePage')); // Lazy-loaded
-
-// Show a spinner while the profile is loading
-}>
-
-
-```
-
-Suspense for Data Fetching is a new feature that lets you also use `` to **declaratively "wait" for anything else, including data.** This page focuses on the data fetching use case, but it can also wait for images, scripts, or other asynchronous work.
-
-- [What Is Suspense, Exactly?](#what-is-suspense-exactly)
- - [What Suspense Is Not](#what-suspense-is-not)
- - [What Suspense Lets You Do](#what-suspense-lets-you-do)
-- [Using Suspense in Practice](#using-suspense-in-practice)
- - [What If I Don’t Use Relay?](#what-if-i-dont-use-relay)
- - [For Library Authors](#for-library-authors)
-- [Traditional Approaches vs Suspense](#traditional-approaches-vs-suspense)
- - [Approach 1: Fetch-on-Render (not using Suspense)](#approach-1-fetch-on-render-not-using-suspense)
- - [Approach 2: Fetch-Then-Render (not using Suspense)](#approach-2-fetch-then-render-not-using-suspense)
- - [Approach 3: Render-as-You-Fetch (using Suspense)](#approach-3-render-as-you-fetch-using-suspense)
-- [Start Fetching Early](#start-fetching-early)
- - [We’re Still Figuring This Out](#were-still-figuring-this-out)
-- [Suspense and Race Conditions](#suspense-and-race-conditions)
- - [Race Conditions with useEffect](#race-conditions-with-useeffect)
- - [Race Conditions with componentDidUpdate](#race-conditions-with-componentdidupdate)
- - [The Problem](#the-problem)
- - [Solving Race Conditions with Suspense](#solving-race-conditions-with-suspense)
-- [Handling Errors](#handling-errors)
-- [Next Steps](#next-steps)
-
-## What Is Suspense, Exactly? {#what-is-suspense-exactly}
-
-Suspense lets your components "wait" for something before they can render. In [this example](https://codesandbox.io/s/frosty-hermann-bztrp), two components wait for an asynchronous API call to fetch some data:
-
-```js
-const resource = fetchProfileData();
-
-function ProfilePage() {
- return (
- Loading profile...}>
-
- Loading posts...}>
-
-
-
- );
-}
-
-function ProfileDetails() {
- // Try to read user info, although it might not have loaded yet
- const user = resource.user.read();
- return
{user.name}
;
-}
-
-function ProfileTimeline() {
- // Try to read posts, although they might not have loaded yet
- const posts = resource.posts.read();
- return (
-
- {posts.map(post => (
-
{post.text}
- ))}
-
- );
-}
-```
-
-**[Try it on CodeSandbox](https://codesandbox.io/s/frosty-hermann-bztrp)**
-
-This demo is a teaser. Don't worry if it doesn't quite make sense yet. We'll talk more about how it works below. Keep in mind that Suspense is more of a *mechanism*, and particular APIs like `fetchProfileData()` or `resource.posts.read()` in the above example are not very important. If you're curious, you can find their definitions right in the [demo sandbox](https://codesandbox.io/s/frosty-hermann-bztrp).
-
-Suspense is not a data fetching library. It's a **mechanism for data fetching libraries** to communicate to React that *the data a component is reading is not ready yet*. React can then wait for it to be ready and update the UI. At Facebook, we use Relay and its [new Suspense integration](https://relay.dev/docs/en/experimental/step-by-step). We expect that other libraries like Apollo can provide similar integrations.
-
-In the long term, we intend Suspense to become the primary way to read asynchronous data from components -- no matter where that data is coming from.
-
-### What Suspense Is Not {#what-suspense-is-not}
-
-Suspense is significantly different from existing approaches to these problems, so reading about it for the first time often leads to misconceptions. Let's clarify the most common ones:
-
- * **It is not a data fetching implementation.** It does not assume that you use GraphQL, REST, or any other particular data format, library, transport, or protocol.
-
- * **It is not a ready-to-use client.** You can't "replace" `fetch` or Relay with Suspense. But you can use a library that's integrated with Suspense (for example, [new Relay APIs](https://relay.dev/docs/en/experimental/api-reference)).
-
- * **It does not couple data fetching to the view layer.** It helps orchestrate displaying the loading states in your UI, but it doesn't tie your network logic to React components.
-
-### What Suspense Lets You Do {#what-suspense-lets-you-do}
-
-So what's the point of Suspense? There are a few ways we can answer this:
-
-* **It lets data fetching libraries deeply integrate with React.** If a data fetching library implements Suspense support, using it from React components feels very natural.
-
-* **It lets you orchestrate intentionally designed loading states.** It doesn't say _how_ the data is fetched, but it lets you closely control the visual loading sequence of your app.
-
-* **It helps you avoid race conditions.** Even with `await`, asynchronous code is often error-prone. Suspense feels more like reading data *synchronously* — as if it were already loaded.
-
-## Using Suspense in Practice {#using-suspense-in-practice}
-
-At Facebook, so far we have only used the Relay integration with Suspense in production. **If you're looking for a practical guide to get started today, [check out the Relay Guide](https://relay.dev/docs/en/experimental/step-by-step)!** It demonstrates patterns that have already worked well for us in production.
-
-**The code demos on this page use a "fake" API implementation rather than Relay.** This makes them easier to understand if you're not familiar with GraphQL, but they won't tell you the "right way" to build an app with Suspense. This page is more conceptual and is intended to help you see *why* Suspense works in a certain way, and which problems it solves.
-
-### What If I Don't Use Relay? {#what-if-i-dont-use-relay}
-
-If you don't use Relay today, you might have to wait before you can really try Suspense in your app. So far, it's the only implementation that we tested in production and are confident in.
-
-Over the next several months, many libraries will appear with different takes on Suspense APIs. **If you prefer to learn when things are more stable, you might prefer to ignore this work for now, and come back when the Suspense ecosystem is more mature.**
-
-You can also write your own integration for a data fetching library, if you'd like.
-
-### For Library Authors {#for-library-authors}
-
-We expect to see a lot of experimentation in the community with other libraries. There is one important thing to note for data fetching library authors.
-
-Although it's technically doable, Suspense is **not** currently intended as a way to start fetching data when a component renders. Rather, it lets components express that they're "waiting" for data that is *already being fetched*. **[Building Great User Experiences with Concurrent Mode and Suspense](/blog/2019/11/06/building-great-user-experiences-with-concurrent-mode-and-suspense.html) describes why this matters and how to implement this pattern in practice.**
-
-Unless you have a solution that helps prevent waterfalls, we suggest to prefer APIs that favor or enforce fetching before render. For a concrete example, you can look at how [Relay Suspense API](https://relay.dev/docs/en/experimental/api-reference#usepreloadedquery) enforces preloading. Our messaging about this hasn't been very consistent in the past. Suspense for Data Fetching is still experimental, so you can expect our recommendations to change over time as we learn more from production usage and understand the problem space better.
-
-## Traditional Approaches vs Suspense {#traditional-approaches-vs-suspense}
-
-We could introduce Suspense without mentioning the popular data fetching approaches. However, this makes it more difficult to see which problems Suspense solves, why these problems are worth solving, and how Suspense is different from the existing solutions.
-
-Instead, we'll look at Suspense as a logical next step in a sequence of approaches:
-
-* **Fetch-on-render (for example, `fetch` in `useEffect`):** Start rendering components. Each of these components may trigger data fetching in their effects and lifecycle methods. This approach often leads to "waterfalls".
-* **Fetch-then-render (for example, Relay without Suspense):** Start fetching all the data for the next screen as early as possible. When the data is ready, render the new screen. We can't do anything until the data arrives.
-* **Render-as-you-fetch (for example, Relay with Suspense):** Start fetching all the required data for the next screen as early as possible, and start rendering the new screen *immediately — before we get a network response*. As data streams in, React retries rendering components that still need data until they're all ready.
-
->Note
->
->This is a bit simplified, and in practice solutions tend to use a mix of different approaches. Still, we will look at them in isolation to better contrast their tradeoffs.
-
-To compare these approaches, we'll implement a profile page with each of them.
-
-### Approach 1: Fetch-on-Render (not using Suspense) {#approach-1-fetch-on-render-not-using-suspense}
-
-A common way to fetch data in React apps today is to use an effect:
-
-```js
-// In a function component:
-useEffect(() => {
- fetchSomething();
-}, []);
-
-// Or, in a class component:
-componentDidMount() {
- fetchSomething();
-}
-```
-
-We call this approach "fetch-on-render" because it doesn't start fetching until *after* the component has rendered on the screen. This leads to a problem known as a "waterfall".
-
-Consider these `` and `` components:
-
-```js{4-6,22-24}
-function ProfilePage() {
- const [user, setUser] = useState(null);
-
- useEffect(() => {
- fetchUser().then(u => setUser(u));
- }, []);
-
- if (user === null) {
- return
- );
-}
-```
-
-**[Try it on CodeSandbox](https://codesandbox.io/s/fragrant-glade-8huj6)**
-
-If you run this code and watch the console logs, you'll notice the sequence is:
-
-1. We start fetching user details
-2. We wait...
-3. We finish fetching user details
-4. We start fetching posts
-5. We wait...
-6. We finish fetching posts
-
-If fetching user details takes three seconds, we'll only *start* fetching the posts after three seconds! That's a "waterfall": an unintentional *sequence* that should have been parallelized.
-
-Waterfalls are common in code that fetches data on render. They're possible to solve, but as the product grows, many people prefer to use a solution that guards against this problem.
-
-### Approach 2: Fetch-Then-Render (not using Suspense) {#approach-2-fetch-then-render-not-using-suspense}
-
-Libraries can prevent waterfalls by offering a more centralized way to do data fetching. For example, Relay solves this problem by moving the information about the data a component needs to statically analyzable *fragments*, which later get composed into a single query.
-
-On this page, we don't assume knowledge of Relay, so we won't be using it for this example. Instead, we'll write something similar manually by combining our data fetching methods:
-
-```js
-function fetchProfileData() {
- return Promise.all([
- fetchUser(),
- fetchPosts()
- ]).then(([user, posts]) => {
- return {user, posts};
- })
-}
-```
-
-In this example, `` waits for both requests but starts them in parallel:
-
-```js{1,2,8-13}
-// Kick off fetching as early as possible
-const promise = fetchProfileData();
-
-function ProfilePage() {
- const [user, setUser] = useState(null);
- const [posts, setPosts] = useState(null);
-
- useEffect(() => {
- promise.then(data => {
- setUser(data.user);
- setPosts(data.posts);
- });
- }, []);
-
- if (user === null) {
- return
- );
-}
-```
-
-**[Try it on CodeSandbox](https://codesandbox.io/s/wandering-morning-ev6r0)**
-
-The event sequence now becomes like this:
-
-1. We start fetching user details
-2. We start fetching posts
-3. We wait...
-4. We finish fetching user details
-5. We finish fetching posts
-
-We've solved the previous network "waterfall", but accidentally introduced a different one. We wait for *all* data to come back with `Promise.all()` inside `fetchProfileData`, so now we can't render profile details until the posts have been fetched too. We have to wait for both.
-
-Of course, this is possible to fix in this particular example. We could remove the `Promise.all()` call, and wait for both Promises separately. However, this approach gets progressively more difficult as the complexity of our data and component tree grows. It's hard to write reliable components when arbitrary parts of the data tree may be missing or stale. So fetching all data for the new screen and *then* rendering is often a more practical option.
-
-### Approach 3: Render-as-You-Fetch (using Suspense) {#approach-3-render-as-you-fetch-using-suspense}
-
-In the previous approach, we fetched data before we called `setState`:
-
-1. Start fetching
-2. Finish fetching
-3. Start rendering
-
-With Suspense, we still start fetching first, but we flip the last two steps around:
-
-1. Start fetching
-2. **Start rendering**
-3. **Finish fetching**
-
-**With Suspense, we don't wait for the response to come back before we start rendering.** In fact, we start rendering *pretty much immediately* after kicking off the network request:
-
-```js{2,17,23}
-// This is not a Promise. It's a special object from our Suspense integration.
-const resource = fetchProfileData();
-
-function ProfilePage() {
- return (
- Loading profile...}>
-
- Loading posts...}>
-
-
-
- );
-}
-
-function ProfileDetails() {
- // Try to read user info, although it might not have loaded yet
- const user = resource.user.read();
- return
{user.name}
;
-}
-
-function ProfileTimeline() {
- // Try to read posts, although they might not have loaded yet
- const posts = resource.posts.read();
- return (
-
- {posts.map(post => (
-
{post.text}
- ))}
-
- );
-}
-```
-
-**[Try it on CodeSandbox](https://codesandbox.io/s/frosty-hermann-bztrp)**
-
-Here's what happens when we render `` on the screen:
-
-1. We've already kicked off the requests in `fetchProfileData()`. It gave us a special "resource" instead of a Promise. In a realistic example, it would be provided by our data library's Suspense integration, like Relay.
-2. React tries to render ``. It returns `` and `` as children.
-3. React tries to render ``. It calls `resource.user.read()`. None of the data is fetched yet, so this component "suspends". React skips over it, and tries rendering other components in the tree.
-4. React tries to render ``. It calls `resource.posts.read()`. Again, there's no data yet, so this component also "suspends". React skips over it too, and tries rendering other components in the tree.
-5. There's nothing left to try rendering. Because `` suspended, React shows the closest `` fallback above it in the tree: `
Loading profile...
`. We're done for now.
-
-This `resource` object represents the data that isn't there yet, but might eventually get loaded. When we call `read()`, we either get the data, or the component "suspends".
-
-**As more data streams in, React will retry rendering, and each time it might be able to progress "deeper".** When `resource.user` is fetched, the `` component will render successfully and we'll no longer need the `
Loading profile...
` fallback. Eventually, we'll get all the data, and there will be no fallbacks on the screen.
-
-This has an interesting implication. Even if we use a GraphQL client that collects all data requirements in a single request, *streaming the response lets us show more content sooner*. Because we render-*as-we-fetch* (as opposed to *after* fetching), if `user` appears in the response earlier than `posts`, we'll be able to "unlock" the outer `` boundary before the response even finishes. We might have missed this earlier, but even the fetch-then-render solution contained a waterfall: between fetching and rendering. Suspense doesn't inherently suffer from this waterfall, and libraries like Relay take advantage of this.
-
-Note how we eliminated the `if (...)` "is loading" checks from our components. This doesn't only remove boilerplate code, but it also simplifies making quick design changes. For example, if we wanted profile details and posts to always "pop in" together, we could delete the `` boundary between them. Or we could make them independent from each other by giving each *its own* `` boundary. Suspense lets us change the granularity of our loading states and orchestrate their sequencing without invasive changes to our code.
-
-## Start Fetching Early {#start-fetching-early}
-
-If you're working on a data fetching library, there's a crucial aspect of Render-as-You-Fetch you don't want to miss. **We kick off fetching _before_ rendering.** Look at this code example closer:
-
-```js
-// Start fetching early!
-const resource = fetchProfileData();
-
-// ...
-
-function ProfileDetails() {
- // Try to read user info
- const user = resource.user.read();
- return
{user.name}
;
-}
-```
-
-**[Try it on CodeSandbox](https://codesandbox.io/s/frosty-hermann-bztrp)**
-
-Note that the `read()` call in this example doesn't *start* fetching. It only tries to read the data that is **already being fetched**. This difference is crucial to creating fast applications with Suspense. We don't want to delay loading data until a component starts rendering. As a data fetching library author, you can enforce this by making it impossible to get a `resource` object without also starting a fetch. Every demo on this page using our "fake API" enforces this.
-
-You might object that fetching "at the top level" like in this example is impractical. What are we going to do if we navigate to another profile's page? We might want to fetch based on props. The answer to this is **we want to start fetching in the event handlers instead**. Here is a simplified example of navigating between user's pages:
-
-```js{1,2,10,11}
-// First fetch: as soon as possible
-const initialResource = fetchProfileData(0);
-
-function App() {
- const [resource, setResource] = useState(initialResource);
- return (
- <>
-
-
- >
- );
-}
-```
-
-**[Try it on CodeSandbox](https://codesandbox.io/s/infallible-feather-xjtbu)**
-
-With this approach, we can **fetch code and data in parallel**. When we navigate between pages, we don't need to wait for a page's code to load to start loading its data. We can start fetching both code and data at the same time (during the link click), delivering a much better user experience.
-
-This poses a question of how do we know *what* to fetch before rendering the next screen. There are several ways to solve this (for example, by integrating data fetching closer with your routing solution). If you work on a data fetching library, [Building Great User Experiences with Concurrent Mode and Suspense](/blog/2019/11/06/building-great-user-experiences-with-concurrent-mode-and-suspense.html) presents a deep dive on how to accomplish this and why it's important.
-
-### We're Still Figuring This Out {#were-still-figuring-this-out}
-
-Suspense itself as a mechanism is flexible and doesn't have many constraints. Product code needs to be more constrained to ensure no waterfalls, but there are different ways to provide these guarantees. Some questions that we're currently exploring include:
-
-* Fetching early can be cumbersome to express. How do we make it easier to avoid waterfalls?
-* When we fetch data for a page, can the API encourage including data for instant transitions *from* it?
-* What is the lifetime of a response? Should caching be global or local? Who manages the cache?
-* Can Proxies help express lazy-loaded APIs without inserting `read()` calls everywhere?
-* What would the equivalent of composing GraphQL queries look like for arbitrary Suspense data?
-
-Relay has its own answers to some of these questions. There is certainly more than a single way to do it, and we're excited to see what new ideas the React community comes up with.
-
-## Suspense and Race Conditions {#suspense-and-race-conditions}
-
-Race conditions are bugs that happen due to incorrect assumptions about the order in which our code may run. Fetching data in the `useEffect` Hook or in class lifecycle methods like `componentDidUpdate` often leads to them. Suspense can help here, too — let's see how.
-
-To demonstrate the issue, we will add a top-level `` component that renders our `` with a button that lets us **switch between different profiles**:
-
-```js{9-11}
-function getNextId(id) {
- // ...
-}
-
-function App() {
- const [id, setId] = useState(0);
- return (
- <>
-
-
- >
- );
-}
-```
-
-Let's compare how different data fetching strategies deal with this requirement.
-
-### Race Conditions with `useEffect` {#race-conditions-with-useeffect}
-
-First, we'll try a version of our original "fetch in effect" example. We'll modify it to pass an `id` parameter from the `` props to `fetchUser(id)` and `fetchPosts(id)`:
-
-```js{1,5,6,14,19,23,24}
-function ProfilePage({ id }) {
- const [user, setUser] = useState(null);
-
- useEffect(() => {
- fetchUser(id).then(u => setUser(u));
- }, [id]);
-
- if (user === null) {
- return
- );
-}
-```
-
-**[Try it on CodeSandbox](https://codesandbox.io/s/nervous-glade-b5sel)**
-
-Note how we also changed the effect dependencies from `[]` to `[id]` — because we want the effect to re-run when the `id` changes. Otherwise, we wouldn't refetch new data.
-
-If we try this code, it might seem like it works at first. However, if we randomize the delay time in our "fake API" implementation and press the "Next" button fast enough, we'll see from the console logs that something is going very wrong. **Requests from the previous profiles may sometimes "come back" after we've already switched the profile to another ID -- and in that case they can overwrite the new state with a stale response for a different ID.**
-
-This problem is possible to fix (you could use the effect cleanup function to either ignore or cancel stale requests), but it's unintuitive and difficult to debug.
-
-### Race Conditions with `componentDidUpdate` {#race-conditions-with-componentdidupdate}
-
-One might think that this is a problem specific to `useEffect` or Hooks. Maybe if we port this code to classes or use convenient syntax like `async` / `await`, it will solve the problem?
-
-Let's try that:
-
-```js
-class ProfilePage extends React.Component {
- state = {
- user: null,
- };
- componentDidMount() {
- this.fetchData(this.props.id);
- }
- componentDidUpdate(prevProps) {
- if (prevProps.id !== this.props.id) {
- this.fetchData(this.props.id);
- }
- }
- async fetchData(id) {
- const user = await fetchUser(id);
- this.setState({ user });
- }
- render() {
- const { id } = this.props;
- const { user } = this.state;
- if (user === null) {
- return
- );
- }
-}
-```
-
-**[Try it on CodeSandbox](https://codesandbox.io/s/trusting-clarke-8twuq)**
-
-This code is deceptively easy to read.
-
-Unfortunately, neither using a class nor the `async` / `await` syntax helped us solve this problem. This version suffers from exactly the same race conditions, for the same reasons.
-
-### The Problem {#the-problem}
-
-React components have their own "lifecycle". They may receive props or update state at any point in time. However, each asynchronous request *also* has its own "lifecycle". It starts when we kick it off, and finishes when we get a response. The difficulty we're experiencing is "synchronizing" several processes in time that affect each other. This is hard to think about.
-
-### Solving Race Conditions with Suspense {#solving-race-conditions-with-suspense}
-
-Let's rewrite this example again, but using Suspense only:
-
-```js
-const initialResource = fetchProfileData(0);
-
-function App() {
- const [resource, setResource] = useState(initialResource);
- return (
- <>
-
-
- >
- );
-}
-
-function ProfilePage({ resource }) {
- return (
- Loading profile...}>
-
- Loading posts...}>
-
-
-
- );
-}
-
-function ProfileDetails({ resource }) {
- const user = resource.user.read();
- return
- );
-}
-```
-
-**[Try it on CodeSandbox](https://codesandbox.io/s/infallible-feather-xjtbu)**
-
-In the previous Suspense example, we only had one `resource`, so we held it in a top-level variable. Now that we have multiple resources, we moved it to the ``'s component state:
-
-```js{4}
-const initialResource = fetchProfileData(0);
-
-function App() {
- const [resource, setResource] = useState(initialResource);
-```
-
-When we click "Next", the `` component kicks off a request for the next profile, and passes *that* object down to the `` component:
-
-```js{4,8}
- <>
-
-
- >
-```
-
-Again, notice that **we're not waiting for the response to set the state. It's the other way around: we set the state (and start rendering) immediately after kicking off a request**. As soon as we have more data, React "fills in" the content inside `` components.
-
-This code is very readable, but unlike the examples earlier, the Suspense version doesn't suffer from race conditions. You might be wondering why. The answer is that in the Suspense version, we don't have to think about *time* as much in our code. Our original code with race conditions needed to set the state *at the right moment later*, or otherwise it would be wrong. But with Suspense, we set the state *immediately* -- so it's harder to mess it up.
-
-## Handling Errors {#handling-errors}
-
-When we write code with Promises, we might use `catch()` to handle errors. How does this work with Suspense, given that we don't *wait* for Promises to start rendering?
-
-With Suspense, handling fetching errors works the same way as handling rendering errors -- you can render an [error boundary](/docs/error-boundaries.html) anywhere to "catch" errors in components below.
-
-First, we'll define an error boundary component to use across our project:
-
-```js
-// Error boundaries currently have to be classes.
-class ErrorBoundary extends React.Component {
- state = { hasError: false, error: null };
- static getDerivedStateFromError(error) {
- return {
- hasError: true,
- error
- };
- }
- render() {
- if (this.state.hasError) {
- return this.props.fallback;
- }
- return this.props.children;
- }
-}
-```
-
-And then we can put it anywhere in the tree to catch errors:
-
-```js{5,9}
-function ProfilePage() {
- return (
- Loading profile...}>
-
- Could not fetch posts.}>
- Loading posts...}>
-
-
-
-
- );
-}
-```
-
-**[Try it on CodeSandbox](https://codesandbox.io/s/adoring-goodall-8wbn7)**
-
-It would catch both rendering errors *and* errors from Suspense data fetching. We can have as many error boundaries as we like but it's best to [be intentional](https://aweary.dev/fault-tolerance-react/) about their placement.
-
-## Next Steps {#next-steps}
-
-We've now covered the basics of Suspense for Data Fetching! Importantly, we now better understand *why* Suspense works this way, and how it fits into the data fetching space.
-
-Suspense answers some questions, but it also poses new questions of its own:
-
-* If some component "suspends", does the app freeze? How to avoid this?
-* What if we want to show a spinner in a different place than "above" the component in a tree?
-* If we intentionally *want* to show an inconsistent UI for a small period of time, can we do that?
-* Instead of showing a spinner, can we add a visual effect like "greying out" the current screen?
-* Why does our [last Suspense example](https://codesandbox.io/s/infallible-feather-xjtbu) log a warning when clicking the "Next" button?
-
-To answer these questions, we will refer to the next section on [Concurrent UI Patterns](/docs/concurrent-mode-patterns.html).
diff --git a/content/docs/conditional-rendering.md b/content/docs/conditional-rendering.md
deleted file mode 100644
index 0c113ff1d..000000000
--- a/content/docs/conditional-rendering.md
+++ /dev/null
@@ -1,242 +0,0 @@
----
-id: conditional-rendering
-title: Умовний рендеринг
-permalink: docs/conditional-rendering.html
-prev: handling-events.html
-next: lists-and-keys.html
-redirect_from:
- - "tips/false-in-jsx.html"
----
-
-React дозволяє розподілити логіку на окремі компоненти. Ці компоненти можна показувати або ховати в залежності від поточного стану додатку.
-
-Умовний рендеринг у React працює так само, як і умовні вирази працюють в JavaScript. Іноді потрібно пояснити React, як стан впливає на те, які компоненти треба сховати, а які — відрендерити, та як саме. Для цього використовуйте [умовний оператор](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Conditional_Operator) JavaScript, або вирази подібні до [`if`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/if...else).
-
-Розглянемо два компоненти:
-
-```js
-function UserGreeting(props) {
- return
З поверненням!
;
-}
-
-function GuestGreeting(props) {
- return
Зареєструйтеся, будь-ласка.
;
-}
-```
-
-Ми створимо компонент `Greeting`, який відображає один з цих компонентів у залежності від того, чи користувач ввійшов до сайту:
-
-```javascript{3-7,11,12}
-function Greeting(props) {
- const isLoggedIn = props.isLoggedIn;
- if (isLoggedIn) {
- return ;
- }
- return ;
-}
-
-ReactDOM.render(
- // Спробуйте замінити значення isLoggedIn на true та подивіться на ефект.
- ,
- document.getElementById('root')
-);
-```
-
-[**Спробувати на CodePen**](https://codepen.io/gaearon/pen/ZpVxNq?editors=0011)
-
-У цьому прикладі різне вітання відрендериться в залежності від значення пропсу `isLoggedIn`.
-
-### Змінні-елементи {#element-variables}
-
-Ви можете використовувати змінні для того, щоб зберігати елементи React. Це допоможе вам умовно рендерити лише частину компонента, в той час, як інша частина компонента залишається незмінною.
-
-Розглянемо ще два компоненти, що представляють кнопки Увійти(Login) та Вийти (Logout)
-
-```js
-function LoginButton(props) {
- return (
-
- );
-}
-
-function LogoutButton(props) {
- return (
-
- );
-}
-```
-
-У наступному прикладі ми створимо [компонент зі станом](/docs/state-and-lifecycle.html#adding-local-state-to-a-class) під назвою `LoginControl`.
-
-Він відрендерить ``, або `` в залежності від поточного стану. Він також відрендерить `` з минулого прикладу:
-
-```javascript{20-25,29,30}
-class LoginControl extends React.Component {
- constructor(props) {
- super(props);
- this.handleLoginClick = this.handleLoginClick.bind(this);
- this.handleLogoutClick = this.handleLogoutClick.bind(this);
- this.state = {isLoggedIn: false};
- }
-
- handleLoginClick() {
- this.setState({isLoggedIn: true});
- }
-
- handleLogoutClick() {
- this.setState({isLoggedIn: false});
- }
-
- render() {
- const isLoggedIn = this.state.isLoggedIn;
- let button;
-
- if (isLoggedIn) {
- button = ;
- } else {
- button = ;
- }
-
- return (
-
-
- {button}
-
- );
- }
-}
-
-ReactDOM.render(
- ,
- document.getElementById('root')
-);
-```
-
-[**Спробувати на CodePen**](https://codepen.io/gaearon/pen/QKzAgB?editors=0010)
-
-Незважаючи на те, що оголошення змінної та використання `if`-виразів для умовного рендерингу є гарним варіантом, але іноді хочеться коротший синтаксис. Для цього існують декілька інших способів для написання умов прямо в JSX, які ми розглянемо нижче.
-
-### Вбудовані умови if з логічним оператором && {#inline-if-with-logical--operator}
-
-Ви можете [вставляти будь-який вираз у JSX](/docs/introducing-jsx.html#embedding-expressions-in-jsx), охопивши його фігурними дужками. Це правило поширюється і на логічний оператор `&&` JavaScript, яким можна зручно вставити елемент в залежності від умови:
-
-```js{6-10}
-function Mailbox(props) {
- const unreadMessages = props.unreadMessages;
- return (
-
-
Доброго дня!
- {unreadMessages.length > 0 &&
-
- У вас {unreadMessages.length} непрочитаних повідомлень.
-
- }
-
- );
-}
-
-const messages = ['React', 'Re: React', 'Re:Re: React'];
-ReactDOM.render(
- ,
- document.getElementById('root')
-);
-```
-
-[**Спробувати на CodePen**](https://codepen.io/gaearon/pen/ozJddz?editors=0010)
-
-Цей приклад працює коректно, тому що в JavaScript вираз `true && expression` завжди обчислюється як `expression`, а вираз `false && expression` — як `false`.
-
-Отже, якщо умова правдива (`true`), то елемент, який йде безпосередньо після `&&`, з'явиться у виводі. Якщо ж умова помилкова (`false`), React проігнорує та пропустить його.
-
-### Вбудовані умови if-else з тернарним оператором {#inline-if-else-with-conditional-operator}
-
-Іншим методом для умовного рендерингу елементів є використання тернарного оператора [`condition ? true : false`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Conditional_Operator).
-
-У наступному прикладі ми використаємо цей метод для того, щоб відрендерити маленький шматочок тексту.
-
-```javascript{5}
-render() {
- const isLoggedIn = this.state.isLoggedIn;
- return (
-
- Користувач {isLoggedIn ? 'зараз' : 'не'} на сайті.
-
- );
-}
-```
-
-Цей метод також можна використувати для більших виразів, але це може зробити код менш очевидним:
-
-```js{5,7,9}
-render() {
- const isLoggedIn = this.state.isLoggedIn;
- return (
-
- {isLoggedIn
- ?
- :
- }
-
- );
-}
-```
-
-Як у JavaScript, так і в React вибір синтаксису залежить від ваших уподобань і прийнятого у вашій команді стилю. Також пам'ятайте, що якщо якась умова стає занадто складною, можливо прийшов час [вилучити частину коду в окремий компонент](/docs/components-and-props.html#extracting-components).
-
-### Запобігання рендерингу компонента {#preventing-component-from-rendering}
-
-Зрідка може виникнути потреба в тому, щоб дозволити компоненту сховати себе, навіть якщо він вже був відрендереним іншим компонентом. Для цього поверніть `null` замість того, що зазвичай йде на рендеринг.
-
-У наступному прикладі, `` буде відрендерено в залежності від значення пропу `warn`. Якщо значення пропу `false`, тоді компонент нічого не рендерить:
-
-```javascript{2-4,29}
-function WarningBanner(props) {
- if (!props.warn) {
- return null;
- }
-
- return (
-
- );
- }
-}
-
-ReactDOM.render(
- ,
- document.getElementById('root')
-);
-```
-
-[**Спробувати на CodePen**](https://codepen.io/gaearon/pen/Xjoqwm?editors=0010)
-
-Повернення `null` із методу `render` ніяк не впливає на спрацювання методів життєвого циклу компонента. Наприклад, `componentDidUpdate` все одно буде викликаний.
diff --git a/content/docs/context.md b/content/docs/context.md
deleted file mode 100644
index b4e8afe4d..000000000
--- a/content/docs/context.md
+++ /dev/null
@@ -1,266 +0,0 @@
----
-id: context
-title: Контекст
-permalink: docs/context.html
----
-
-Контекст забезпечує спосіб передавати дані через дерево компонентів без необхідності передавати пропси вручну на кожному рівні.
-
-У типовому додатку React дані передаються зверху вниз (від батьківської до дочірньої компоненти) через пропси, але це може бути громіздким для певних типів реквізитів (наприклад, налаштування локалі, тема інтерфейсу користувача), які потрібні багатьом компонентам програми. Контекст надає спосіб обмінюватися значеннями, подібними до цих, між компонентами без необхідності явно передавати властивість через кожен рівень дерева.
-
-- [Коли використовувати контекст](#when-to-use-context)
-- [Перед використанням контексту](#before-you-use-context)
-- [API](#api)
- - [React.createContext](#reactcreatecontext)
- - [Context.Provider](#contextprovider)
- - [Class.contextType](#classcontexttype)
- - [Context.Consumer](#contextconsumer)
- - [Context.displayName](#contextdisplayname)
-- [Examples](#examples)
- - [Dynamic Context](#dynamic-context)
- - [Updating Context from a Nested Component](#updating-context-from-a-nested-component)
- - [Consuming Multiple Contexts](#consuming-multiple-contexts)
-- [Caveats](#caveats)
-- [Legacy API](#legacy-api)
-
-## Коли використовувати контекст {#when-to-use-context}
-
-Контекст призначений для обміну даними, які можна вважати «глобальними» для дерева компонентів React, таких як поточний автентифікований користувач, тема чи бажана мова. Наприклад, у наведеному нижче коді ми вручну прокидаємо проп `theme`, щоб стилізувати компонент Button:
-
-`embed:context/motivation-problem.js`
-
-Використовуючи контекст, ми можемо уникнути проходження атрибутів через проміжні елементи:
-
-`embed:context/motivation-solution.js`
-
-## Перед використанням контексту {#before-you-use-context}
-
-Контекст в основному використовується, коли деякі дані повинні бути доступні *багатьом* компонентам на різних рівнях вкладеності. Застосовуйте його економно, оскільки це ускладнює повторне використання компонентів.
-
-**Якщо ви тільки хочете уникнути проходження деяких реквізитів через багато рівнів, [композиція компонентів](/docs/composition-vs-inheritance.html) часто є простішим рішенням, ніж контекст.**
-
-Наприклад, розглянемо компонент `Page`, який передає властивість `user` і `avatarSize` на кілька рівнів нижче, щоб глибоко вкладені компоненти `Link` і `Avatar` могли прочитати його:
-
-```js
-
-// ... який рендерить ...
-
-// ... який рендерить ...
-
-// ... який рендерить ...
-
-
-
-```
-
-Може здатися зайвим передавати властивості `user` і `avatarSize` через багато рівнів, якщо зрештою вони дійсно потрібні лише компоненту `Avatar`. Також дратує те, що щоразу, коли компонент `Avatar` потребує додаткових реквізитів зверху, ви також повинні додавати їх на всіх проміжних рівнях.
-
-Один із способів вирішити цю проблему **без контексту** — це [передавати сам компонент `Avatar`](/docs/composition-vs-inheritance.html#containment) щоб проміжним компонентам не потрібно було знати про властивості `user` або `avatarSize`:
-
-```js
-function Page(props) {
- const user = props.user;
- const userLink = (
-
-
-
- );
- return ;
-}
-
-// Теперь ми маємо:
-
-// ... який рендерить ...
-
-// ... який рендерить ...
-
-// ... який рендерить ...
-{props.userLink}
-```
-
-Завдяки цій зміні лише верхній компонент Page має знати про використання `user` і `avatarSize` компонентами `Link` і `Avatar`.
-
-Ця *інверсія керування* може зробити ваш код чистішим у багатьох випадках, зменшивши кількість реквізитів, які потрібно пропустити через вашу програму, і надавши більше контролю кореневим компонентам. Однак це не завжди правильний вибір: переміщення більшої складності вище в дереві робить компоненти вищого рівня складнішими та змушує компоненти нижчого рівня бути більш гнучкими, ніж вам хочеться.
-
-Ви не обмежені одним дочірнім компонентом. Ви можете передати кілька дочірніх компонентів або навіть мати кілька окремих "слотів" для дочірніх компонентів, [як описано тут](/docs/composition-vs-inheritance.html#containment):
-
-```js
-function Page(props) {
- const user = props.user;
- const content = ;
- const topBar = (
-
-
-
-
-
- );
- return (
-
- );
-}
-```
-
-Ціого паттерну достатньо для багатьох випадків, коли потрібно відділити дочірній компонент від найближчих батьків. Ви можете піти ще далі за допомогою [рендер-пропси](/docs/render-props.html) якщо дочірня компонента потребує взаємодії з батьківською перед рендерингом.
-
-Однак іноді ті самі дані повинні бути доступні багатьом компонентам у дереві та на різних рівнях вкладеності. Контекст дозволяє вам "транслювати" такі дані та зміни до них усім компонентам нижче. Поширені приклади, коли використання контексту може бути простішим, ніж альтернативи, включають керування поточною мовою, темою або кеш-пам’яттю даних.
-
-## API {#api}
-
-### `React.createContext` {#reactcreatecontext}
-
-```js
-const MyContext = React.createContext(defaultValue);
-```
-
-Створює об’єкт Context. Коли React відтворює компонент, який підписується на цей об’єкт Context, він читатиме поточне значення контексту з найближчого відповідного `Provider` над ним у дереві.
-
-Аргумент `defaultValue` використовується **тільки**, коли компонент не має відповідного провайдера над ним у дереві. Це може бути корисним для тестування компонентів ізольовано без їх упаковки. Примітка: передача `undefined` як значення провайдера не призводить до використання споживаючими компонентами `defaultValue`.
-
-### `Context.Provider` {#contextprovider}
-
-```js
-
-```
-
-Every Context object comes with a Provider React component that allows consuming components to subscribe to context changes.
-
-Accepts a `value` prop to be passed to consuming components that are descendants of this Provider. One Provider can be connected to many consumers. Providers can be nested to override values deeper within the tree.
-
-All consumers that are descendants of a Provider will re-render whenever the Provider's `value` prop changes. The propagation from Provider to its descendant consumers (including [`.contextType`](#classcontexttype) and [`useContext`](/docs/hooks-reference.html#usecontext)) is not subject to the `shouldComponentUpdate` method, so the consumer is updated even when an ancestor component skips an update.
-
-Changes are determined by comparing the new and old values using the same algorithm as [`Object.is`](//developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is#Description).
-
-> Note
->
-> The way changes are determined can cause some issues when passing objects as `value`: see [Caveats](#caveats).
-
-### `Class.contextType` {#classcontexttype}
-
-```js
-class MyClass extends React.Component {
- componentDidMount() {
- let value = this.context;
- /* perform a side-effect at mount using the value of MyContext */
- }
- componentDidUpdate() {
- let value = this.context;
- /* ... */
- }
- componentWillUnmount() {
- let value = this.context;
- /* ... */
- }
- render() {
- let value = this.context;
- /* render something based on the value of MyContext */
- }
-}
-MyClass.contextType = MyContext;
-```
-
-The `contextType` property on a class can be assigned a Context object created by [`React.createContext()`](#reactcreatecontext). This lets you consume the nearest current value of that Context type using `this.context`. You can reference this in any of the lifecycle methods including the render function.
-
-> Note:
->
-> You can only subscribe to a single context using this API. If you need to read more than one see [Consuming Multiple Contexts](#consuming-multiple-contexts).
->
-> If you are using the experimental [public class fields syntax](https://babeljs.io/docs/plugins/transform-class-properties/), you can use a **static** class field to initialize your `contextType`.
-
-
-```js
-class MyClass extends React.Component {
- static contextType = MyContext;
- render() {
- let value = this.context;
- /* render something based on the value */
- }
-}
-```
-
-### `Context.Consumer` {#contextconsumer}
-
-```js
-
- {value => /* render something based on the context value */}
-
-```
-
-A React component that subscribes to context changes. This lets you subscribe to a context within a [function component](/docs/components-and-props.html#function-and-class-components).
-
-Requires a [function as a child](/docs/render-props.html#using-props-other-than-render). The function receives the current context value and returns a React node. The `value` argument passed to the function will be equal to the `value` prop of the closest Provider for this context above in the tree. If there is no Provider for this context above, the `value` argument will be equal to the `defaultValue` that was passed to `createContext()`.
-
-> Note
->
-> For more information about the 'function as a child' pattern, see [render props](/docs/render-props.html).
-
-### `Context.displayName` {#contextdisplayname}
-
-Context object accepts a `displayName` string property. React DevTools uses this string to determine what to display for the context.
-
-For example, the following component will appear as MyDisplayName in the DevTools:
-
-```js{2}
-const MyContext = React.createContext(/* some value */);
-MyContext.displayName = 'MyDisplayName';
-
- // "MyDisplayName.Provider" in DevTools
- // "MyDisplayName.Consumer" in DevTools
-```
-
-## Examples {#examples}
-
-### Dynamic Context {#dynamic-context}
-
-A more complex example with dynamic values for the theme:
-
-**theme-context.js**
-`embed:context/theme-detailed-theme-context.js`
-
-**themed-button.js**
-`embed:context/theme-detailed-themed-button.js`
-
-**app.js**
-`embed:context/theme-detailed-app.js`
-
-### Updating Context from a Nested Component {#updating-context-from-a-nested-component}
-
-It is often necessary to update the context from a component that is nested somewhere deeply in the component tree. In this case you can pass a function down through the context to allow consumers to update the context:
-
-**theme-context.js**
-`embed:context/updating-nested-context-context.js`
-
-**theme-toggler-button.js**
-`embed:context/updating-nested-context-theme-toggler-button.js`
-
-**app.js**
-`embed:context/updating-nested-context-app.js`
-
-### Consuming Multiple Contexts {#consuming-multiple-contexts}
-
-To keep context re-rendering fast, React needs to make each context consumer a separate node in the tree.
-
-`embed:context/multiple-contexts.js`
-
-If two or more context values are often used together, you might want to consider creating your own render prop component that provides both.
-
-## Caveats {#caveats}
-
-Because context uses reference identity to determine when to re-render, there are some gotchas that could trigger unintentional renders in consumers when a provider's parent re-renders. For example, the code below will re-render all consumers every time the Provider re-renders because a new object is always created for `value`:
-
-`embed:context/reference-caveats-problem.js`
-
-
-To get around this, lift the value into the parent's state:
-
-`embed:context/reference-caveats-solution.js`
-
-## Legacy API {#legacy-api}
-
-> Note
->
-> React previously shipped with an experimental context API. The old API will be supported in all 16.x releases, but applications using it should migrate to the new version. The legacy API will be removed in a future major React version. Read the [legacy context docs here](/docs/legacy-context.html).
-
diff --git a/content/docs/create-a-new-react-app.md b/content/docs/create-a-new-react-app.md
deleted file mode 100644
index d53845e2e..000000000
--- a/content/docs/create-a-new-react-app.md
+++ /dev/null
@@ -1,94 +0,0 @@
----
-id: create-a-new-react-app
-title: Створюємо новий React-додаток
-permalink: docs/create-a-new-react-app.html
-redirect_from:
- - "docs/add-react-to-a-new-app.html"
-prev: add-react-to-a-website.html
-next: cdn-links.html
----
-
-Для більш комфортної роботи використовуйте вбудований набір інструментів.
-
-Ця сторінка описує декілька популярних наборів інструментів для роботи з React, що допоможуть вам з такими задачами як:
-
-* Масштабування великої кількості компонентів та файлів.
-* Використання сторонніх бібліотек з npm.
-* Раннє виявлення розповсюджених помилок.
-* Миттєве відстеження змін у CSS та JS файлах.
-* Оптимізація коду для продакшну.
-
-Набори інструментів описані на цій сторінці **не потребують додаткового налаштування для початку роботи з ними**.
-
-## Чи додаткові інструменти необхідні для вас? {#you-might-not-need-a-toolchain}
-
-Якщо у вас не виникає проблем з вище описаними ситуаціями, або ж якщо ви ще не відчуваєте себе достатньо впевнено для використання інструменів для роботи з JavaScript, розгляньте можливість [додання React за допомогою тегу `
-```
-
-Also ensure the CDN responds with the `Access-Control-Allow-Origin: *` HTTP header:
-
-
-
-### Webpack {#webpack}
-
-#### Source maps {#source-maps}
-
-Some JavaScript bundlers may wrap the application code with `eval` statements in development. (For example Webpack will do this if [`devtool`](https://webpack.js.org/configuration/devtool/) is set to any value containing the word "eval".) This may cause errors to be treated as cross-origin.
-
-If you use Webpack, we recommend using the `cheap-module-source-map` setting in development to avoid this problem.
-
-#### Code splitting {#code-splitting}
-
-If your application is split into multiple bundles, these bundles may be loaded using JSONP. This may cause errors thrown in the code of these bundles to be treated as cross-origin.
-
-To resolve this, use the [`crossOriginLoading`](https://webpack.js.org/configuration/output/#output-crossoriginloading) setting in development to add the `crossorigin` attribute to the `
-
-```
-
-Пам'ятайте, що для продакшну підходять тільки ті файли React, що закінчуються на `.production.min.js`.
-
-### Brunch {#brunch}
-
-Для найефективнішої продакшн-збірки з використанням Brunch, встановіть плагін [`terser-brunch`](https://github.com/brunch/terser-brunch):
-
-```
-# Якщо ви користуєтесь npm
-npm install --save-dev uglify-js-brunch
-
-# Якщо ви користуєтесь Yarn
-yarn add --dev uglify-js-brunch
-```
-
-Потім створіть продакшн-збірку, додавши прапорець `-p` до команди `build`:
-
-```
-brunch build -p
-```
-
-Пам'ятайте, що це потрібно робити лише для продакшн-збірок. Ви не повинні передавати прапорець `-p` чи застосовувати цей плагін під час розробки, тому що це приховає корисні попередження від React та сповільнить процес збірки.
-
-### Browserify {#browserify}
-
-Для найефективнішої продакшн-збірки з використанням Browserify, встановіть декілька плагінів:
-
-```
-# Якщо ви користуєтесь npm
-npm install --save-dev envify terser uglifyify
-
-# Якщо ви користуєтесь Yarn
-yarn add --dev envify terser uglifyify
-```
-
-Щоб створити продакшн-збірку, впевніться, що ви додали наступні перетворення **(у представленому порядку)**:
-
-* Плагін [`envify`](https://github.com/hughsk/envify) гарантує правильність встановленого середовища для збірки. Зробіть його глобальним (`-g`).
-* Плагін [`uglifyify`](https://github.com/hughsk/uglifyify) видаляє необхідні для розробки імпорти. Зробіть його глобальним також (`-g`).
-* Нарешті, отримана збірка передається до [`terser`](https://github.com/terser-js/terser) для мініфікації ([прочитайте навіщо](https://github.com/hughsk/uglifyify#motivationusage)).
-
-Наприклад:
-
-```
-browserify ./index.js \
- -g [ envify --NODE_ENV production ] \
- -g uglifyify \
- | terser --compress --mangle > ./bundle.js
-```
-
-Пам'ятайте, що це потрібно робити лише для продакшн-збірок. Ви не повинні використовувати ці плагіни під час розробки, тому що це приховає корисні попередження від React та сповільнить процес збірки.
-
-### Rollup {#rollup}
-
-Для найефективнішої продакшн-збірки з використанням Rollup, встановіть декілька плагінів:
-
-```bash
-# Якщо ви користуєтесь npm
-npm install --save-dev rollup-plugin-commonjs rollup-plugin-replace rollup-plugin-terser
-
-# Якщо ви користуєтесь Yarn
-yarn add --dev rollup-plugin-commonjs rollup-plugin-replace rollup-plugin-terser
-```
-
-Щоб створити продакшн-збірку, впевніться, що ви додали наступні плагіни **(у представленому порядку)**:
-
-* Плагін [`replace`](https://github.com/rollup/rollup-plugin-replace) гарантує правильність встановленого середовища для збірки.
-* Плагін [`commonjs`](https://github.com/rollup/rollup-plugin-commonjs) надає підтримку CommonJS у Rollup.
-* Плагін [`terser`](https://github.com/TrySound/rollup-plugin-terser) стискає та мініфікує фінальну збірку.
-
-```js
-plugins: [
- // ...
- require('rollup-plugin-replace')({
- 'process.env.NODE_ENV': JSON.stringify('production')
- }),
- require('rollup-plugin-commonjs')(),
- require('rollup-plugin-terser')(),
- // ...
-]
-```
-
-Для більш повного зразку налаштування [перегляньте цей gist](https://gist.github.com/Rich-Harris/cb14f4bc0670c47d00d191565be36bf0).
-
-Пам'ятайте, що це потрібно робити лише для продакшн-збірок. Ви не повинні використовувати плагін `terser` чи `replace` із значенням `'production'` під час розробки, тому що це приховає корисні попередження від React та сповільнить процес збірки.
-
-### webpack {#webpack}
-
->**Примітка:**
->
->Якщо ви використовуєте Create React App, то використовуйте [інструкції вище](#create-react-app).
->Цей розділ потрібен, якщо ви самі налаштовуєте webpack.
-
-Webpack версії 4, або вище, за замовчуванням мінімізує ваш код у продакшн-режимі.
-
-```js
-const TerserPlugin = require('terser-webpack-plugin');
-
-module.exports = {
- mode: 'production',
- optimization: {
- minimizer: [new TerserPlugin({ /* additional options here */ })],
- },
-};
-```
-
-Ви можете дізнатися про це більше у [документації webpack](https://webpack.js.org/guides/production/).
-
-Пам'ятайте, що це потрібно робити лише для продакшн-збірок. Ви не повинні використовувати `UglifyJsPlugin` чи `TerserPlugin` під час розробки, тому що це приховає корисні попередження від React та сповільнить процес збірки.
-
-## Профілювання компонентів з використанням вкладки Chrome "Performance" {#profiling-components-with-the-chrome-performance-tab}
-
-У режимі **розробки**, ви можете візуалізувати процес монтування, оновлення і демонтування компонентів, використавши інструменти продуктивності у браузерах, що їх підтримують. Наприклад:
-
-
-
-Щоб зробити це в Chrome:
-
-1. Тимчасово **вимкніть всі розширення Chrome, особливо React DevTools**. Вони можуть істотно спотворити резульати!
-
-2. Впевніться, що додаток запущений в режимі розробки.
-
-3. Відкрийте Chrome DevTools, оберіть вкладку **[Performance](https://developers.google.com/web/tools/chrome-devtools/evaluate-performance/timeline-tool)** та натисніть **Record**.
-
-4. Виконайте дії, які потрібно профілювати. Не записуйте більше 20 секунд, інакше Chrome може зависнути.
-
-5. Зупиніть запис.
-
-6. Події React будуть згруповані під міткою **User Timing**.
-
-Для більш детальних інструкцій перегляньте [цю статтю Бена Шварца (Ben Schwarz)](https://calibreapp.com/blog/react-performance-profiling-optimization).
-
-Зверніть увагу на те, **що ці значення відносні і компоненти в продакшні будуть рендеритись швидше**. Проте це допоможе вам зрозуміти, коли не пов'язані між собою частини інтерфейсу оновлюються через помилку та як глибоко і часто ці оновлення вібдуваються.
-
-Наразі Chrome, Edge та IE є єдиними браузерами, котрі підтримують цю функціональність, але ми використовуємо стандарт [User Timing API](https://developer.mozilla.org/en-US/docs/Web/API/User_Timing_API), а тому очікуємо, що більше браузерів додадуть її підтримку.
-
-## Профілювання компонентів з профайлером DevTools {#profiling-components-with-the-devtools-profiler}
-
-`react-dom` 16.5+ та `react-native` 0.57+ надають додаткові можливості профілювання в режимі розробки з використанням профайлера React DevTools.
-Огляд профайлера можна знайти в пості блогу ["Знайомство з React Profiler"](/blog/2018/09/10/introducing-the-react-profiler.html).
-Відео-посібник також [доступний на YouTube](https://www.youtube.com/watch?v=nySib7ipZdk).
-
-Якщо ви ще не встановили React DevTools, ви можете знайти їх тут:
-
-- [Розширення браузера Chrome](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en)
-- [Розширення браузера Firefox](https://addons.mozilla.org/en-GB/firefox/addon/react-devtools/)
-- [Окремий пакунок Node](https://www.npmjs.com/package/react-devtools)
-
-> Примітка
->
-> Продакшн-збірка профілювання для `react-dom` також доступна як `react-dom/profiling`.
-> Докладніше про її використання ви можете дізнатись за посиланням [fb.me/react-profiling](https://fb.me/react-profiling)
-
-## Віртуалізація довгих списків {#virtualize-long-lists}
-
-Якщо ваш додаток рендерить довгі списки даних (сотні чи тисячі рядків), ми радимо використовувати підхід під назвою "віконний доступ". Цей підхід рендерить лише невелику підмножину ваших рядків у будь-який момент часу і може значно зменшити час, потрібний для повторного рендеру компонентів та кількість створених DOM-вузлів.
-
-[react-window](https://react-window.now.sh/) та [react-virtualized](https://bvaughn.github.io/react-virtualized/) — це популярні бібліотеки для віконного доступу. Вони надають кілька компонентів для відображення списків, сіток та табличних даних. Якщо ваш додаток потребує іншого підходу, то ви можете створити власний компонент для віконного доступу, як це зроблено в [Twitter](https://medium.com/@paularmstrong/twitter-lite-and-high-performance-react-progressive-web-apps-at-scale-d28a00e780a3).
-
-## Уникнення узгодження {#avoid-reconciliation}
-
-React створює і підтримує внутрішній стан відображуваного користувацького інтерфейсу. Він також включає React-елементи, які ви повертаєте з ваших компонентів. Це дозволяє React уникати створення нових DOM-вузлів та доступу до вже існуючих без необхідності, тому що ці операції можуть бути повільнішими за операції зі звичайними JavaScript-об'єктами. Іноді цей стан називають "віртуальний DOM", але в React Native він працює так само.
-
-Коли пропси чи стан компонента змінюються, React вирішує чи необхідне оновлення DOM, порівнюючи новий повернутий елемент з вже відрендереним. Якщо вони не рівні, то React оновить DOM.
-
-Незважаючи на те, що React оновлює тільки змінені вузли DOM, повторний рендер все ж займає певний час. У більшості випадків це не проблема, але якщо ви помітите, що швидкодія зменшиться, то ви можете прискорити все, перевизначивши метод життєвого циклу `shouldComponentUpdate`, котрий викликається перед початком процесу повторного рендерингу. За замовчуванням, реалізація цієї функції повертає `true`, змушуючи React здійснити оновлення:
-
-```javascript
-shouldComponentUpdate(nextProps, nextState) {
- return true;
-}
-```
-
-Якщо ви знаєте, що в певних ситуаціях ваш компонент не повинен оновлюватись, то ви можете повернути `false` з `shouldComponentUpdate`, щоб пропустити весь процес рендерингу, включно з викликом `render()` поточного компонента та компонентів нижче.
-
-У більшості випадків, замість написання `shouldComponentUpdate()` вручну, ви можете наслідуватись від [`React.PureComponent`](/docs/react-api.html#reactpurecomponent). Це еквівалентно реалізації `shouldComponentUpdate()` з поверховим порівнянням поточних та попередніч пропсів та стану.
-
-## shouldComponentUpdate в дії {#shouldcomponentupdate-in-action}
-
-На рисунку зображено піддерево компонентів. Для кожного з них `SCU` позначає значення, повернуте `shouldComponentUpdate`, і `vDOMEq` позначає чи були відрендерені React-елементи рівними. Нарешті, колір кола позначає те, чи має компонент бути узгодженим, чи ні.
-
-
-
-Оскільки `shouldComponentUpdate` повернув `false` для піддерева з коренем в C2, React не буде намагатися відрендерити C2 і навіть викликати `shouldComponentUpdate` для C4 і C5.
-
-Для C1 і C3 `shouldComponentUpdate` повернув `true`, тому React має перейти вниз до листів дерева і перевірити їх. Для C6 `shouldComponentUpdate` повернув `true` і, оскільки значення відрендерених елементів не було еквівалентним, React має оновити DOM.
-
-Останнім цікавим випадком є C8. React має відрендерити цей компонент, але оскільки повернуті React-елементи були рівні попереднім, то DOM не буде оновлений.
-
-Зверніть увагу на те, що React повинен був здійснити зміну DOM лише для C6, що було неминучим. Для C8 він уникнув змін завдяки порівнянню відрендерених React-елементів, а для піддерева C2 та C7 не потрібно було навіть виконувати це порівняння, оскільки процес рендерингу зупинився у методі `shouldComponentUpdate` і метод `render` не був викликаний.
-
-## Приклади {#examples}
-
-Якщо ваш компонент має змінюватись лише тоді, коли змінюються змінні `props.color` чи `state.count`, ви можете виконати цю перевірку в `shouldComponentUpdate`:
-
-```javascript
-class CounterButton extends React.Component {
- constructor(props) {
- super(props);
- this.state = {count: 1};
- }
-
- shouldComponentUpdate(nextProps, nextState) {
- if (this.props.color !== nextProps.color) {
- return true;
- }
- if (this.state.count !== nextState.count) {
- return true;
- }
- return false;
- }
-
- render() {
- return (
-
- );
- }
-}
-```
-
-У цьому коді `shouldComponentUpdate` лише перевіряє наявні зміни в `props.color` чи `state.count`. Якщо ці значення не змінились, то компонент не оновиться. Якщо ваш компонент буде більш складним, ви можете використати схожий шаблон і зробити "поверхове порівняння" всіх полей `props` і `state`, щоб визначити, чи має компонент оновитись. Цей шаблон трапляється часто, а тому React надає допоміжну функцію для цієї логіки — просто унаслідуйтесь від `React.PureComponent`. Наступний код показує простіший шлях для досягнення цього ефекту:
-
-```js
-class CounterButton extends React.PureComponent {
- constructor(props) {
- super(props);
- this.state = {count: 1};
- }
-
- render() {
- return (
-
- );
- }
-}
-```
-
-У більшості випадків ви можете використовувати `React.PureComponent` замість написання власного методу `shouldComponentUpdate`. Він робить лише поверхове порівняння, а тому ви не можете використати його, якщо пропси чи стан можуть змінитись таким чином, що поверхове порівняння пропустить цю зміну.
-
-Це може бути проблемою для більш складних структур даних. Наприклад, ви хочете, щоб компонент `ListOfWords` рендерив список слів розділених комами з батьківським компонентом `WordAdder`, що дає можливість натиснути на кнопку і додати слово в список. Цей код працює *неправильно*:
-
-```javascript
-class ListOfWords extends React.PureComponent {
- render() {
- return
- );
- }
-}
-```
-
-Проблема в тому, що `PureComponent` зробить просте порівняння старого значення `this.props.words` з новим. Оскільки цей код змінює масив `words` у методі `handleClick` класу `WordAdder`, то нове та старе значення `this.props.words` будуть вважатися однаковими як посилання, хоча вміст масиву і змінився. `ListOfWords` не оновиться, хоч він і містить нові слова, що мають бути відрендерені.
-
-## Сила незмінності даних {#the-power-of-not-mutating-data}
-
-Найпростішим шляхом уникнення цієї проблеми є уникнення зміни значень, які ви використовуєте як пропси чи стан. Наприклад, метод `handleClick` вище, міг би бути переписаний з використанням `concat`:
-
-```javascript
-handleClick() {
- this.setState(state => ({
- words: state.words.concat(['марклар'])
- }));
-}
-```
-
-ES6 підтримує [синтаксис розпакування](https://developer.mozilla.org/uk/docs/Web/JavaScript/Reference/Operators/%D0%9E%D0%BF%D0%B5%D1%80%D0%B0%D1%82%D0%BE%D1%80_%D1%80%D0%BE%D0%B7%D0%BF%D0%B0%D0%BA%D1%83%D0%B2%D0%B0%D0%BD%D0%BD%D1%8F) для масивів, щоб спростити цю задачу. Якщо ви використовуєте Create React App, цей синтаксис доступний за замовчуванням.
-
-```js
-handleClick() {
- this.setState(state => ({
- words: [...state.words, 'марклар'],
- }));
-};
-```
-
-Ви також можете подібним чином переписати код, що змінює об'єкти. Наприклад, у нас є об'єкт `colormap` і ми хочемо написати функцію, що змінить `colormap.right` на `'blue'`. Ми могли б написати:
-
-```js
-function updateColorMap(colormap) {
- colormap.right = 'blue';
-}
-```
-
-Щоб переписати це без зміни оригінального об'єкта, ми можемо використати метод [Object.assign](https://developer.mozilla.org/uk/docs/Web/JavaScript/Reference/Global_Objects/Object/assign):
-
-```js
-function updateColorMap(colormap) {
- return Object.assign({}, colormap, {right: 'blue'});
-}
-```
-
-`updateColorMap` тепер повертає новий об'єкт, а не змінює старий. `Object.assign` — це ES6 і для його роботи потрібен поліфіл.
-
-[Оператор розкладу](https://developer.mozilla.org/uk/docs/Web/JavaScript/Reference/Operators/Spread_syntax) дозволяє оновлювати об'єкти, не мутуючи їх:
-
-```js
-function updateColorMap(colormap) {
- return {...colormap, right: 'blue'};
-}
-```
-
-Ця функція була додана до JavaScript у ES2018.
-
-Якщо ви використовуєте Create React App, то `Object.assign` та розпакування об'єктів доступні за замовчуванням.
-
-Коли ви працюєте з глибоко вкладеними об'єктами, то постійне іх оновлення може заплутати вас. Якщо ви зіткнулися з такою проблемою, зверніть увагу на [Immer](https://github.com/mweststrate/immer) або [immutability-helper](https://github.com/kolodny/immutability-helper). Ці бібліотеки допомогають писати читабельний код, не втрачаючи переваг незмінності.
diff --git a/content/docs/portals.md b/content/docs/portals.md
deleted file mode 100644
index d3ba86821..000000000
--- a/content/docs/portals.md
+++ /dev/null
@@ -1,154 +0,0 @@
----
-id: portals
-title: Портали
-permalink: docs/portals.html
----
-
-Портали дозволяють рендерити дочірні елементи в DOM-вузол, який знаходиться за межами DOM-ієрархії батьківського компонента.
-
-```js
-ReactDOM.createPortal(child, container)
-```
-
-Перший аргумент (`child`) — це [будь-який React-компонент, який може бути відрендерений](/docs/react-component.html#render), такий як елемент, строка або фрагмент. Другий аргумент (`container`) — це DOM-елемент.
-
-## Застосування {#usage}
-
-Зазвичай, коли ви повертаєте елемент з рендер-методу компонента, він монтується в DOM як дочірній елемент найближчого батьківського вузла:
-
-```js{4,6}
-render() {
- // React монтує новий div і рендерить в нього дочірні елементи
- return (
-
- {this.props.children}
-
- );
-}
-```
-
-Однак іноді потрібно помістити дочірній елемент в інше місце в DOM:
-
-```js{6}
-render() {
- // React *не* створює новий div. Він рендерить дочірні елементи в `domNode`.
- // `domNode` — це будь-який валідний DOM-вузол, що знаходиться в будь-якому місці в DOM.
- return ReactDOM.createPortal(
- this.props.children,
- domNode
- );
-}
-```
-
-Типовий випадок застосування порталів — коли в батьківському компоненті задані стилі `overflow: hidden` або `z-index`, але вам потрібно щоб дочірній елемент візуально виходив за рамки свого контейнера. Наприклад, діалоги, спливаючі картки та спливаючі підказки.
-
-> Примітка:
->
-> При роботі з порталами пам'ятайте, що потрібно приділити увагу [управлінню фокусом за допомогою клавіатури](/docs/accessibility.html#programmatically-managing-focus).
->
-> Для модальних діалогів переконайтеся, що будь-який користувач буде здатний взаємодіяти з ними, слідуючи [практикам розробки модальних вікон WAI-ARIA](https://www.w3.org/TR/wai-aria-practices-1.1/#dialog_modal).
-
-[**Спробувати на CodePen**](https://codepen.io/gaearon/pen/yzMaBd)
-
-## Спливання подій через портали {#event-bubbling-through-portals}
-
-Як вже було сказано, портал може перебувати в будь-якому місці DOM-дерева. Незважаючи на це, у всіх інших аспектах він поводиться як звичайний React-компонент. Такі можливості, як контекст, працюють звичним чином, навіть якщо нащадок є порталом, оскільки сам портал все ще знаходиться в *React-дереві*, незважаючи на його розташування в *DOM-дереві*.
-
-Так само працює і спливання подій. Подія, згенерована зсередини порталу, буде поширюватися до батьків, що містяться у *React-дереві*, навіть якщо ці елементи не є батьківськими в *DOM-дереві*. Припустимо, що є наступна HTML-структура:
-
-```html
-
-
-
-
-
-
-```
-
-`Батьківський` компонент в `#app-root` зможе зловити неперехоплену спливаючу подію з сусіднього вузла `#modal-root`.
-
-```js{28-31,42-49,53,61-63,70-71,74}
-// Це два сусідніх контейнера в DOM
-const appRoot = document.getElementById('app-root');
-const modalRoot = document.getElementById('modal-root');
-
-class Modal extends React.Component {
- constructor(props) {
- super(props);
- this.el = document.createElement('div');
- }
-
- componentDidMount() {
- // Елемент порталу додається в DOM-дерево після того, як
- // дочірні компоненти Modal будуть змонтовані, а це означає,
- // що дочірні компоненти будуть монтуватися на окремому DOM-вузлі.
- // Якщо дочірній компонент повинен бути приєднаний до DOM-дерева
- // відразу при підключенні, наприклад, для вимірювань DOM-вузла
- // або виклику в дочірньому елементі 'autoFocus', додайте в компонент Modal
- // стан і рендеріть дочірні елементи тільки тоді, коли
- // компонент Modal вже вставлений в DOM-дерево.
- modalRoot.appendChild(this.el);
- }
-
- componentWillUnmount() {
- modalRoot.removeChild(this.el);
- }
-
- render() {
- return ReactDOM.createPortal(
- this.props.children,
- this.el
- );
- }
-}
-
-class Parent extends React.Component {
- constructor(props) {
- super(props);
- this.state = {clicks: 0};
- this.handleClick = this.handleClick.bind(this);
- }
-
- handleClick() {
- // Ця функція буде викликана при натисканні на кнопку в компоненті Child
- // і оновить стан компонента Parent, незважаючи на те,
- // що кнопка не є прямим нащадком в DOM.
- this.setState(state => ({
- clicks: state.clicks + 1
- }));
- }
-
- render() {
- return (
-
-
Кількість натискань: {this.state.clicks}
-
- Відкрийте DevTools браузера,
- щоб переконатися, що кнопка
- не є нащадком блоку div
- з обробником onClick.
-
-
-
-
-
- );
- }
-}
-
-function Child() {
- // Подія натискання на цю кнопку буде спливати вгору до батьківського елемента,
- // тому що не визначено атрибут "onClick"
- return (
-
-
-
- );
-}
-
-ReactDOM.render(, appRoot);
-```
-
-[**Спробувати на CodePen**](https://codepen.io/gaearon/pen/jGBWpE)
-
-Перехоплення подій, що спливають від порталу до батьківського компоненту, дозволяє створювати абстракції, що не спроектовані спеціально під портали. Наприклад, ви відрендерили компонент ``. Тоді його події можуть бути перехоплені батьківським компонентом, незалежно від того, чи був `` реалізований з використанням порталів чи без них.
diff --git a/content/docs/react-without-es6.md b/content/docs/react-without-es6.md
deleted file mode 100644
index 004bc3c4d..000000000
--- a/content/docs/react-without-es6.md
+++ /dev/null
@@ -1,225 +0,0 @@
----
-id: react-without-es6
-title: React без ES6
-permalink: docs/react-without-es6.html
----
-
-Зазвичай, ви б оголосили React-компонент у вигляді JavaScript-класу:
-
-```javascript
-class Greeting extends React.Component {
- render() {
- return
Привіт, {this.props.name}
;
- }
-}
-```
-
-Якщо ви досі не використовуєте ES6, ви можете використати пакет `create-react-class`:
-
-
-```javascript
-var createReactClass = require('create-react-class');
-var Greeting = createReactClass({
- render: function() {
- return
Привіт, {this.props.name}
;
- }
-});
-```
-
-API ES6-класів схожий до `createReactClass()` за деякими виключеннями.
-
-## Оголошення властивостей компонента {#declaring-default-props}
-
-За допомогою функцій та класів ES6 `defaultProps` оголошуються як властивість самого компонента:
-
-```javascript
-class Greeting extends React.Component {
- // ...
-}
-
-Greeting.defaultProps = {
- name: 'Марія'
-};
-```
-
-Використовуючи `createReactClass()`, вам необхідно визначити метод `getDefaultProps()` як функцію в переданому об'єкті:
-
-```javascript
-var Greeting = createReactClass({
- getDefaultProps: function() {
- return {
- name: 'Марія'
- };
- },
-
- // ...
-
-});
-```
-
-## Встановлення початкового стану компонента {#setting-the-initial-state}
-
-Використовуючи ES6-класи, ви можете визначити початковий стан через `this.state` у конструкторі:
-
-```javascript
-class Counter extends React.Component {
- constructor(props) {
- super(props);
- this.state = {count: props.initialCount};
- }
- // ...
-}
-```
-
-З `createReactClass()` ви маєте створити окремий метод `getInitialState`, який поверне початковий стан:
-
-```javascript
-var Counter = createReactClass({
- getInitialState: function() {
- return {count: this.props.initialCount};
- },
- // ...
-});
-```
-
-## Автоприв'язка {#autobinding}
-
-У React-компонентах оголошених як ES6-класи, методи дотримуються такої ж семантики, як і звичайні ES6-класи. Це означає, що вони не виконують прив'язку `this` до екземпляру компонента автоматично. Вам необхідно буде явно використати `.bind(this)` у конструкторі:
-
-```javascript
-class SayHello extends React.Component {
- constructor(props) {
- super(props);
- this.state = {message: 'Привіт!'};
- // Цей рядок -- дуже важливий!
- this.handleClick = this.handleClick.bind(this);
- }
-
- handleClick() {
- alert(this.state.message);
- }
-
- render() {
- // Оскільки `this.handleClick` є прив'язаним у конструкторі екземпляра, то ми можемо його використати як обробник події.
- return (
-
- );
- }
-}
-```
-
-З використанням `createReactClass()` це необов'язково, оскільки цей метод прив'язує всі методи до екземпляра компонента:
-
-```javascript
-var SayHello = createReactClass({
- getInitialState: function() {
- return {message: 'Привіт!'};
- },
-
- handleClick: function() {
- alert(this.state.message);
- },
-
- render: function() {
- return (
-
- );
- }
-});
-```
-
-Це означає, що ES6-класи пишуться із трохи більш універсальним кодом для обробників подій, але при цьому продуктивність величезних додатків є трохи вищою.
-
-Якщо універсальний код для вас не занадто привабливий, ви можете увімкнути **експериментальну** пропозицію синтаксису [Class Properties](https://babeljs.io/docs/plugins/transform-class-properties/) з Babel:
-
-
-```javascript
-class SayHello extends React.Component {
- constructor(props) {
- super(props);
- this.state = {message: 'Привіт!'};
- }
- // УВАГА: цей синтаксис є експериментальним!
- // Тут стрілкова функція виконує прив'язку:
- handleClick = () => {
- alert(this.state.message);
- }
-
- render() {
- return (
-
- );
- }
-}
-```
-
-Зверніть увагу, що синтаксис, описаний вище, є **експериментальним** і він може змінитися, або пропозиція не буде внесена в стандарт мови.
-
-Якщо ви за безпечний варіант, то ось ще варіанти:
-
-* Прив'язуйте методи в конструкторі.
-* Використовуйте стрілкові функції, наприклад, `onClick={(e) => this.handleClick(e)}`.
-* Використовуйте `createReactClass` і далі.
-
-## Міксини {#mixins}
-
->**Примітка:**
->
->ES6 був випущений без підтримки міксинів. Тому немає ніякої підтримки міксинів, коли ви використовуєте React з ES6-класами.
->
->**Ми також знайшли безліч проблем у кодових базах, що використовують міксини, [і не рекомендуємо використовувати їх у розробці](/blog/2016/07/13/mixins-considered-harmful.html).**
->
->Цей розділ існує тільки для довідки.
-
-Інколи дуже різні компоненти можуть мати спільну функціональність. Вони інколи називаються [наскрізна відповідальність](https://uk.wikipedia.org/wiki/Cross-cutting_concern). `createReactClass` дозволяє вам використовувати застарілу систему `mixins`.
-
-Одним із поширених варіантів використання **є** компонент, який бажає оновити себе через деякий проміжок часу. Можна просто використовувати `setInterval()`, але важливо скасувати даний процес, коли вам він не потрібен та для економії пам'яті. React надає [методи життєвого циклу](/docs/react-component.html#the-component-lifecycle), які дозволяють дізнатися, коли компонент буде створений або знищений. Давайте створимо простий міксин, який використовує дані методи для простої функції `setInterval()`, яка автоматично "прибере за собою", коли компонент буде знищений.
-
-```javascript
-var SetIntervalMixin = {
- componentWillMount: function() {
- this.intervals = [];
- },
- setInterval: function() {
- this.intervals.push(setInterval.apply(null, arguments));
- },
- componentWillUnmount: function() {
- this.intervals.forEach(clearInterval);
- }
-};
-
-var createReactClass = require('create-react-class');
-
-var TickTock = createReactClass({
- mixins: [SetIntervalMixin], // Використовуємо міксин
- getInitialState: function() {
- return {seconds: 0};
- },
- componentDidMount: function() {
- this.setInterval(this.tick, 1000); // Викликаємо метод на міксині
- },
- tick: function() {
- this.setState({seconds: this.state.seconds + 1});
- },
- render: function() {
- return (
-
- React працював {this.state.seconds} секунд.
-
- );
- }
-});
-
-ReactDOM.render(
- ,
- document.getElementById('example')
-);
-```
-
-Якщо компонент використовує декілька міксинів і вони визначають одинакові методи життєвого циклу (наприклад, декілька міксинів хочуть виконати очистку коли компонент буде знищеним), всі методи життєвого циклу будуть гарантовано викликані. Методи, визначені на міксинах, запускаються в порядку перерахування міксинів після виклику методу на компоненті.
diff --git a/content/docs/react-without-jsx.md b/content/docs/react-without-jsx.md
deleted file mode 100644
index 37acbbc6e..000000000
--- a/content/docs/react-without-jsx.md
+++ /dev/null
@@ -1,59 +0,0 @@
----
-id: react-without-jsx
-title: React без JSX
-permalink: docs/react-without-jsx.html
----
-
-JSX не є вимогою для роботи з React. Використання React без JSX є найзручнішим тоді, коли ви не бажаєте налаштовувати компіляцію у вашому середовищі збірки.
-
-Кожен JSX-елемент являє собою "синтаксичний цукор" для виклику `React.createElement(component, props, ...children)`. Отже, все що можна зробити за допомогою JSX, може також бути виконаним на чистому JavaScript.
-
-Наприклад, ось код на JSX:
-
-```js
-class Hello extends React.Component {
- render() {
- return
Привіт, {this.props.toWhat}
;
- }
-}
-
-ReactDOM.render(
- ,
- document.getElementById('root')
-);
-```
-
-Його можна переписати таким чином, що JSX не буде використовуватися:
-
-```js
-class Hello extends React.Component {
- render() {
- return React.createElement('div', null, `Привіт, ${this.props.toWhat}`);
- }
-}
-
-ReactDOM.render(
- React.createElement(Hello, {toWhat: 'світе'}, null),
- document.getElementById('root')
-);
-```
-
-Якщо ви зацікавлені в інших прикладах того, як JSX компілюється в JavaScript-код, спробуйте [онлайн Babel-компілятор](babel://jsx-simple-example).
-
-Компонент може бути представлений у вигляді рядку, як підклас `React.Component` або у вигляді звичайної функції.
-
-Якщо вас втомлює написання `React.createElement`, поширеною практикою є призначення "скорочення":
-
-```js
-const e = React.createElement;
-
-ReactDOM.render(
- e('div', null, 'Привіт, світе'),
- document.getElementById('root')
-);
-```
-
-Якщо ви використаєте дане скорочення для `React.createElement`, то робота з React без JSX буде такою ж зручною.
-
-Також ви можете ознайомитися з іншими проектами, як [`react-hyperscript`](https://github.com/mlmorg/react-hyperscript) і [`hyperscript-helpers`](https://github.com/ohanhi/hyperscript-helpers), які пропонують більш короткий синтаксис.
-
diff --git a/content/docs/reconciliation.md b/content/docs/reconciliation.md
deleted file mode 100644
index ab8886b8d..000000000
--- a/content/docs/reconciliation.md
+++ /dev/null
@@ -1,157 +0,0 @@
----
-id: reconciliation
-title: Reconciliation
-permalink: docs/reconciliation.html
----
-
-React provides a declarative API so that you don't have to worry about exactly what changes on every update. This makes writing applications a lot easier, but it might not be obvious how this is implemented within React. This article explains the choices we made in React's "diffing" algorithm so that component updates are predictable while being fast enough for high-performance apps.
-
-## Motivation {#motivation}
-
-When you use React, at a single point in time you can think of the `render()` function as creating a tree of React elements. On the next state or props update, that `render()` function will return a different tree of React elements. React then needs to figure out how to efficiently update the UI to match the most recent tree.
-
-There are some generic solutions to this algorithmic problem of generating the minimum number of operations to transform one tree into another. However, the [state of the art algorithms](https://grfia.dlsi.ua.es/ml/algorithms/references/editsurvey_bille.pdf) have a complexity in the order of O(n3) where n is the number of elements in the tree.
-
-If we used this in React, displaying 1000 elements would require in the order of one billion comparisons. This is far too expensive. Instead, React implements a heuristic O(n) algorithm based on two assumptions:
-
-1. Two elements of different types will produce different trees.
-2. The developer can hint at which child elements may be stable across different renders with a `key` prop.
-
-In practice, these assumptions are valid for almost all practical use cases.
-
-## The Diffing Algorithm {#the-diffing-algorithm}
-
-When diffing two trees, React first compares the two root elements. The behavior is different depending on the types of the root elements.
-
-### Elements Of Different Types {#elements-of-different-types}
-
-Whenever the root elements have different types, React will tear down the old tree and build the new tree from scratch. Going from `` to ``, or from `` to ``, or from `