diff --git a/beta/src/pages/apis/usecontext.md b/beta/src/pages/apis/usecontext.md
new file mode 100644
index 00000000..66e9bc89
--- /dev/null
+++ b/beta/src/pages/apis/usecontext.md
@@ -0,0 +1,1395 @@
+---
+title: useContext
+---
+
+
+
+`useContext` is a React Hook that lets you read and subscribe to [context](/learn/passing-data-deeply-with-context) from your component.
+
+```js
+const value = useContext(SomeContext)
+```
+
+
+
+- [Usage](#usage)
+ - [Passing data deeply into the tree](#passing-data-deeply-into-the-tree)
+ - [Updating data passed via context](#updating-data-passed-via-context)
+ - [Specifying a fallback default value](#specifying-a-fallback-default-value)
+ - [Overriding context for a part of the tree](#overriding-context-for-a-part-of-the-tree)
+ - [Optimizing re-renders when passing objects and functions](#optimizing-re-renders-when-passing-objects-and-functions)
+- [Reference](#reference)
+ - [`useContext(SomeContext)`](#usecontext)
+- [Troubleshooting](#troubleshooting)
+ - [My component doesn't see the value from my provider](#my-component-doesnt-see-the-value-from-my-provider)
+ - [I am always getting undefined from my context although the default value is different](#i-am-always-getting-undefined-from-my-context-although-the-default-value-is-different)
+
+## Usage {/*usage*/}
+
+
+### Passing data deeply into the tree {/*passing-data-deeply-into-the-tree*/}
+
+Call `useContext` at the top level of your component to read and subscribe to [context](/learn/passing-data-deeply-with-context).
+
+```js [[2, 4, "theme"], [1, 4, "ThemeContext"]]
+import { useContext } from 'react';
+
+function Button() {
+ const theme = useContext(ThemeContext);
+ // ...
+```
+
+`useContext` returns the context value for the context you passed. To determine the context value, React searches the component tree and finds **the closest context provider above** for that particular context.
+
+To pass context to a `Button`, wrap it or one of its parent components into the corresponding context provider:
+
+```js [[1, 3, "ThemeContext"], [2, 3, "\"dark\""], [1, 5, "ThemeContext"]]
+function MyPage() {
+ return (
+
+
+
+ );
+}
+
+function Form() {
+ // ... renders buttons inside ...
+}
+```
+
+It doesn't matter how many layers of components there are between the provider and the `Button`. When a `Button` *anywhere* inside of `Form` calls `useContext(ThemeContext)`, it will receive `"dark"` as the value.
+
+
+
+`useContext()` always looks for the closest provider *above* the component that calls it. It searches upwards and **does not** consider providers in the component from which you're calling `useContext()`.
+
+
+
+
+
+```js
+import { createContext, useContext } from 'react';
+
+const ThemeContext = createContext(null);
+
+export default function MyApp() {
+ return (
+
+
+
+ )
+}
+
+function Form() {
+ return (
+
+
+
+
+ );
+}
+
+function Panel({ title, children }) {
+ const theme = useContext(ThemeContext);
+ const className = 'panel-' + theme;
+ return (
+
+
{title}
+ {children}
+
+ )
+}
+
+function Button({ children }) {
+ const theme = useContext(ThemeContext);
+ const className = 'button-' + theme;
+ return (
+
+ );
+}
+```
+
+```css
+.panel-light,
+.panel-dark {
+ border: 1px solid black;
+ border-radius: 4px;
+ padding: 20px;
+}
+.panel-light {
+ color: #222;
+ background: #fff;
+}
+
+.panel-dark {
+ color: #fff;
+ background: rgb(23, 32, 42);
+}
+
+.button-light,
+.button-dark {
+ border: 1px solid #777;
+ padding: 5px;
+ margin-right: 10px;
+ margin-top: 10px;
+}
+
+.button-dark {
+ background: #222;
+ color: #fff;
+}
+
+.button-light {
+ background: #fff;
+ color: #222;
+}
+```
+
+
+
+---
+
+### Updating data passed via context {/*updating-data-passed-via-context*/}
+
+Often, you'll want the context to change over time. To update context, you need to combine it with [state](/apis/usestate). Declare a state variable in the parent component, and pass the current state down as the context value to the provider.
+
+```js {2} [[1, 4, "ThemeContext"], [2, 4, "theme"], [1, 11, "ThemeContext"]]
+function MyPage() {
+ const [theme, setTheme] = useState('dark');
+ return (
+
+
+
+
+ );
+}
+```
+
+Now any `Button` inside of the provider will receive the current `theme` value. If you call `setTheme` to update the `theme` value that you pass to the provider, all `Button` components will re-render with the new `'light'` value.
+
+
+
+---
+
+### Updating a value via context {/*updating-a-value-via-context*/}
+
+In this example, the `MyApp` component holds a state variable which is then passed to the `ThemeContext` provider. Checking the "Dark mode" checkbox updates the state. Changing the provided value re-renders all the components using that context.
+
+
+
+```js
+import { createContext, useContext, useState } from 'react';
+
+const ThemeContext = createContext(null);
+
+export default function MyApp() {
+ const [theme, setTheme] = useState('light');
+ return (
+
+
+
+
+ )
+}
+
+function Form({ children }) {
+ return (
+
+
+
+
+ );
+}
+
+function Panel({ title, children }) {
+ const theme = useContext(ThemeContext);
+ const className = 'panel-' + theme;
+ return (
+
+
{title}
+ {children}
+
+ )
+}
+
+function Button({ children }) {
+ const theme = useContext(ThemeContext);
+ const className = 'button-' + theme;
+ return (
+
+ );
+}
+```
+
+```css
+.panel-light,
+.panel-dark {
+ border: 1px solid black;
+ border-radius: 4px;
+ padding: 20px;
+ margin-bottom: 10px;
+}
+.panel-light {
+ color: #222;
+ background: #fff;
+}
+
+.panel-dark {
+ color: #fff;
+ background: rgb(23, 32, 42);
+}
+
+.button-light,
+.button-dark {
+ border: 1px solid #777;
+ padding: 5px;
+ margin-right: 10px;
+ margin-top: 10px;
+}
+
+.button-dark {
+ background: #222;
+ color: #fff;
+}
+
+.button-light {
+ background: #fff;
+ color: #222;
+}
+```
+
+
+
+Note that `value="dark"` passes the `"dark"` string, but `value={theme}` passes the value of the JavaScript `theme` variable with [JSX curly braces](/learn/javascript-in-jsx-with-curly-braces). Curly braces also let you pass context values that aren't strings.
+
+
+
+### Updating an object via context {/*updating-an-object-via-context*/}
+
+In this example, there is a `currentUser` state variable which holds an object. You combine `{ currentUser, setCurrentUser }` into a single object and pass it down through the context inside the `value={}`. This lets any component below, such as `LoginButton`, read both `currentUser` and `setCurrentUser`, and then call `setCurrentUser` when needed.
+
+
+
+```js
+import { createContext, useContext, useState } from 'react';
+
+const CurrentUserContext = createContext(null);
+
+export default function MyApp() {
+ const [currentUser, setCurrentUser] = useState(null);
+ return (
+
+
+
+ );
+}
+
+function Form({ children }) {
+ return (
+
+
+
+ );
+}
+
+function LoginButton() {
+ const {
+ currentUser,
+ setCurrentUser
+ } = useContext(CurrentUserContext);
+
+ if (currentUser !== null) {
+ return
+ );
+}
+
+function Task({ task }) {
+ const [isEditing, setIsEditing] = useState(false);
+ const dispatch = useTasksDispatch();
+ let taskContent;
+ if (isEditing) {
+ taskContent = (
+ <>
+ {
+ dispatch({
+ type: 'changed',
+ task: {
+ ...task,
+ text: e.target.value
+ }
+ });
+ }} />
+
+ >
+ );
+ } else {
+ taskContent = (
+ <>
+ {task.text}
+
+ >
+ );
+ }
+ return (
+
+ );
+}
+```
+
+```css
+button { margin: 5px; }
+li { list-style-type: none; }
+ul, li { margin: 0; padding: 0; }
+```
+
+
+
+
+
+
+
+---
+
+### Specifying a fallback default value {/*specifying-a-fallback-default-value*/}
+
+If React can't find any providers of that particular context in the parent tree, the context value returned by `useContext()` will be equal to the default value that you specified when you [created that context](/api/createcontext):
+
+```js [[1, 1, "ThemeContext"], [3, 1, "null"]]
+const ThemeContext = createContext(null);
+```
+
+The default value **never changes**. If you want to update context, use it with state as [described above](#updating-data-passed-via-context).
+
+Often, instead of `null`, there is some more meaningful value you can use as a default, for example:
+
+```js [[1, 1, "ThemeContext"], [3, 1, "light"]]
+const ThemeContext = createContext('light');
+```
+
+This way, if you accidentally render some component without a corresponding provider, it won't break. This also helps your components work well in a test environment without setting up a lot of providers in the tests.
+
+In the example below, the "Toggle theme" button is always light because it's **outside any theme context provider** and the default context theme value is `'light'`. Try editing the default theme to be `'dark'`.
+
+
+
+```js
+import { createContext, useContext, useState } from 'react';
+
+const ThemeContext = createContext('light');
+
+export default function MyApp() {
+ const [theme, setTheme] = useState('light');
+ return (
+ <>
+
+
+
+
+ >
+ )
+}
+
+function Form({ children }) {
+ return (
+
+
+
+
+ );
+}
+
+function Panel({ title, children }) {
+ const theme = useContext(ThemeContext);
+ const className = 'panel-' + theme;
+ return (
+
+
{title}
+ {children}
+
+ )
+}
+
+function Button({ children, onClick }) {
+ const theme = useContext(ThemeContext);
+ const className = 'button-' + theme;
+ return (
+
+ );
+}
+```
+
+```css
+.panel-light,
+.panel-dark {
+ border: 1px solid black;
+ border-radius: 4px;
+ padding: 20px;
+ margin-bottom: 10px;
+}
+.panel-light {
+ color: #222;
+ background: #fff;
+}
+
+.panel-dark {
+ color: #fff;
+ background: rgb(23, 32, 42);
+}
+
+.button-light,
+.button-dark {
+ border: 1px solid #777;
+ padding: 5px;
+ margin-right: 10px;
+ margin-top: 10px;
+}
+
+.button-dark {
+ background: #222;
+ color: #fff;
+}
+
+.button-light {
+ background: #fff;
+ color: #222;
+}
+```
+
+
+
+---
+
+### Overriding context for a part of the tree {/*overriding-context-for-a-part-of-the-tree*/}
+
+You can override the context for a part of the tree by wrapping that part in a provider with a different value.
+
+```js {3,5}
+
+ ...
+
+
+
+ ...
+
+```
+
+You can nest and override providers as many times as you need.
+
+
+
+### Overriding a theme {/*overriding-a-theme*/}
+
+Here, the button *inside* the `Footer` receives a different context value (`"light"`) than the buttons outside (`"dark"`).
+
+
+
+```js
+import { createContext, useContext } from 'react';
+
+const ThemeContext = createContext(null);
+
+export default function MyApp() {
+ return (
+
+
+
+ )
+}
+
+function Form() {
+ return (
+
+
+
+
+
+
+
+ );
+}
+
+function Footer() {
+ return (
+
+ );
+}
+
+function Panel({ title, children }) {
+ const theme = useContext(ThemeContext);
+ const className = 'panel-' + theme;
+ return (
+
+ {title &&
{title}
}
+ {children}
+
+ )
+}
+
+function Button({ children }) {
+ const theme = useContext(ThemeContext);
+ const className = 'button-' + theme;
+ return (
+
+ );
+}
+```
+
+```css
+footer {
+ margin-top: 20px;
+ border-top: 1px solid #aaa;
+}
+
+.panel-light,
+.panel-dark {
+ border: 1px solid black;
+ border-radius: 4px;
+ padding: 20px;
+}
+.panel-light {
+ color: #222;
+ background: #fff;
+}
+
+.panel-dark {
+ color: #fff;
+ background: rgb(23, 32, 42);
+}
+
+.button-light,
+.button-dark {
+ border: 1px solid #777;
+ padding: 5px;
+ margin-right: 10px;
+ margin-top: 10px;
+}
+
+.button-dark {
+ background: #222;
+ color: #fff;
+}
+
+.button-light {
+ background: #fff;
+ color: #222;
+}
+```
+
+
+
+
+
+### Automatically nested headings {/*automatically-nested-headings*/}
+
+You can "accumulate" information when you nest context providers. In this example, the `Section` component keeps track of the `LevelContext` which specifies the depth of the section nesting. It reads the `LevelContext` from the parent section, and provides the `LevelContext` number increased by one to its children. As a result, the `Heading` component can automatically decide which of the `
`, `
`, `
`, ..., tags to use based on how many `Section` components it is nested inside of.
+
+Read a [detailed walkthrough](/learn/passing-data-deeply-with-context) of this example.
+
+
+
+```js
+import Heading from './Heading.js';
+import Section from './Section.js';
+
+export default function Page() {
+ return (
+
+ Title
+
+ Heading
+ Heading
+ Heading
+
+ Sub-heading
+ Sub-heading
+ Sub-heading
+
+ Sub-sub-heading
+ Sub-sub-heading
+ Sub-sub-heading
+
+
+
+
+ );
+}
+```
+
+```js Section.js
+import { useContext } from 'react';
+import { LevelContext } from './LevelContext.js';
+
+export default function Section({ children }) {
+ const level = useContext(LevelContext);
+ return (
+
+
+ {children}
+
+
+ );
+}
+```
+
+```js Heading.js
+import { useContext } from 'react';
+import { LevelContext } from './LevelContext.js';
+
+export default function Heading({ children }) {
+ const level = useContext(LevelContext);
+ switch (level) {
+ case 0:
+ throw Error('Heading must be inside a Section!');
+ case 1:
+ return
+
+---
+
+### Optimizing re-renders when passing objects and functions {/*optimizing-re-renders-when-passing-objects-and-functions*/}
+
+You can pass any values via context, including objects and functions.
+
+```js [[2, 10, "{ currentUser, login }"]]
+function MyApp() {
+ const [currentUser, setCurrentUser] = useState(null);
+
+ function login(response) {
+ storeCredentials(response.credentials);
+ setCurrentUser(response.user);
+ }
+
+ return (
+
+
+
+ );
+}
+```
+
+Here, the context value is a JavaScript object with two properties, one of which is a function. Whenever `MyApp` re-renders (for example, on a route update), this will be a *different* object pointing at a *different* function, so React will also have to re-render all components deep in the tree that call `useContext(AuthContext)`.
+
+In smaller apps, this is not a problem. However, there is no need to re-render them if the underlying data, like `currentUser`, has not changed. To help React take advantage of that fact, you may wrap the `login` function with [`useCallback`](/apis/usecallback) and wrap the object creation into [`useMemo`](/apis/usememo). This is a performance optimization:
+
+```js {1,6-9,11-14}
+import { useCallback, useMemo } from 'react';
+
+function MyApp() {
+ const [currentUser, setCurrentUser] = useState(null);
+
+ const login = useCallback((response) => {
+ storeCredentials(response.credentials);
+ setCurrentUser(response.user);
+ }, []);
+
+ const contextValue = useMemo(() => ({
+ currentUser,
+ login
+ }), [currentUser, login]);
+
+ return (
+
+
+
+ );
+}
+```
+
+The `login` function does not use any information from the render scope, so you can specify an empty array of dependencies. The `contextValue` object consists of `currentUser` and `login`, so it needs to list both as dependencies. As a result of this change, the components calling `useContext(AuthProvider)` won't need to re-render unless `currentUser` changes. Read more about [skipping re-renders with memoization](TODO).
+
+---
+
+## Reference {/*reference*/}
+
+### `useContext(SomeContext)` {/*usecontext*/}
+
+Call `useContext` at the top level of your component to read and subscribe to [context](/learn/passing-data-deeply-with-context).
+
+```js
+import { useContext } from 'react';
+
+function MyComponent() {
+ const theme = useTheme(ThemeContext);
+ // ...
+```
+
+[See more examples above.](#examples-basic)
+
+#### Parameters {/*parameters*/}
+
+* `SomeContext`: The context that you've previously created with [`createContext`](/api/createcontext). The context itself does not hold the information, it only represents the kind of information you can provide or read from components.
+
+#### Returns {/*returns*/}
+
+`useContext` returns the context value for the calling component. It is determined as the `value` passed to the closest `SomeContext.Provider` above the calling component in the tree. If there is no such provider, then the returned value will be the `defaultValue` you have passed to [`createContext`](/api/createcontext) for that context. The returned value is always up-to-date. React automatically re-renders components that read some context if it changes.
+
+#### Caveats {/*caveats*/}
+
+* `useContext()` call in a component is not affected by providers returned from the *same* component. The corresponding `` **needs to be *above*** the component doing the `useContext()` call.
+* React **automatically re-renders** all the children that use a particular context starting from the provider that receives a different `value`. The previous and the next values are compared with the [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) comparison. Skipping re-renders with [`memo`](/apis/memo) does not prevent the children receiving fresh context values from above.
+* If your build system produces duplicates modules in the output (which can happen if you use symlinks), this can break context. Passing something via context only works if `SomeContext` that you use to provide context and `SomeContext` that you use to read it are ***exactly* the same object**, as determined by a `===` comparison.
+
+---
+
+## Troubleshooting {/*troubleshooting*/}
+
+### My component doesn't see the value from my provider {/*my-component-doesnt-see-the-value-from-my-provider*/}
+
+There are a few common ways that this can happen:
+
+1. You're rendering `` in the same component (or below) as where you're calling `useContext()`. Move `` *above and outside* the component calling `useContext()`.
+2. You may have forgotten to wrap your component with ``, or you might have put it in a different part of the tree than you thought. Check whether the hierarchy is right using [React DevTools](/learn/react-developer-tools).
+3. You might be running into some build issue with your tooling that causes `SomeContext` as seen from the providing component and `SomeContext` as seen by the reading component to be two different objects. This can happen if you use symlinks, for example. You can verify this by assigning them to globals like `window.SomeContext1` and `window.SomeContext2` and then checking whether `window.SomeContext1 === window.SomeContext2` in the console. If they're not the same, you need to fix that issue on the build tool level.
+
+### I am always getting `undefined` from my context although the default value is different {/*i-am-always-getting-undefined-from-my-context-although-the-default-value-is-different*/}
+
+You might have a provider without a `value` in the tree:
+
+```js {1,2}
+// 🚩 Doesn't work: no value prop
+
+
+
+```
+
+If you forget to specify `value`, it's like passing `value={undefined}`.
+
+You may have also mistakingly used a different prop name by mistake:
+
+```js {1,2}
+// 🚩 Doesn't work: prop should be called "value"
+
+
+
+```
+
+In both of these cases you should see a warning from React in the console. To fix them, call the prop `value`:
+
+```js {1,2}
+// ✅ Passing the value prop
+
+
+
+```
+
+Note that the [default value from your `createContext(defaultValue)` call](#specifying-a-fallback-default-value) is only used **if there is no matching provider above at all.** If there is a `` component somewhere in the parent tree, the component calling `useContext(SomeContext)` *will* receive `undefined` as the context value.
\ No newline at end of file
diff --git a/beta/src/pages/apis/useref.md b/beta/src/pages/apis/useref.md
index 52448bbe..d9994002 100644
--- a/beta/src/pages/apis/useref.md
+++ b/beta/src/pages/apis/useref.md
@@ -15,6 +15,7 @@ const ref = useRef(initialValue)
- [Usage](#usage)
- [Referencing a value with a ref](#referencing-a-value-with-a-ref)
- [Manipulating the DOM with a ref](#manipulating-the-dom-with-a-ref)
+ - [Exposing a ref from your component](#exposing-a-ref-from-your-component)
- [Avoiding recreating the ref contents](#avoiding-recreating-the-ref-contents)
- [Reference](#reference)
- [`useRef(initialValue)`](#useref)
diff --git a/beta/src/sidebarReference.json b/beta/src/sidebarReference.json
index 37422835..c5245f50 100644
--- a/beta/src/sidebarReference.json
+++ b/beta/src/sidebarReference.json
@@ -15,6 +15,10 @@
"title": "useState()",
"path": "/apis/usestate"
},
+ {
+ "title": "useContext()",
+ "path": "/apis/usecontext"
+ },
{
"title": "useRef()",
"path": "/apis/useref"