mirror of
https://github.com/reactjs/react.dev.git
synced 2026-02-24 20:53:08 +00:00
[Beta] Remove inline useEvent impl (#5101)
This commit is contained in:
@@ -455,8 +455,8 @@ This is not ideal. You want to re-connect to the chat only if the `roomId` has c
|
||||
```json package.json hidden
|
||||
{
|
||||
"dependencies": {
|
||||
"react": "latest",
|
||||
"react-dom": "latest",
|
||||
"react": "experimental",
|
||||
"react-dom": "experimental",
|
||||
"react-scripts": "latest",
|
||||
"toastify-js": "1.12.0"
|
||||
},
|
||||
@@ -471,7 +471,7 @@ This is not ideal. You want to re-connect to the chat only if the `roomId` has c
|
||||
|
||||
```js
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useEvent } from './useEvent.js';
|
||||
import { experimental_useEvent as useEvent } from 'react';
|
||||
import { createConnection, sendMessage } from './chat.js';
|
||||
import { showNotification } from './notifications.js';
|
||||
|
||||
@@ -575,25 +575,6 @@ export function showNotification(message, theme) {
|
||||
}
|
||||
```
|
||||
|
||||
```js useEvent.js
|
||||
import { useRef, useInsertionEffect, useCallback } from 'react';
|
||||
|
||||
// The useEvent API has not yet been added to React,
|
||||
// so this is a temporary shim to make this sandbox work.
|
||||
// You're not expected to write code like this yourself.
|
||||
|
||||
export function useEvent(fn) {
|
||||
const ref = useRef(null);
|
||||
useInsertionEffect(() => {
|
||||
ref.current = fn;
|
||||
}, [fn]);
|
||||
return useCallback((...args) => {
|
||||
const f = ref.current;
|
||||
return f(...args);
|
||||
}, []);
|
||||
}
|
||||
```
|
||||
|
||||
```css
|
||||
label { display: block; margin-top: 10px; }
|
||||
```
|
||||
|
||||
@@ -1253,10 +1253,26 @@ Is there a line of code inside the Effect that should not be reactive? How can y
|
||||
|
||||
<Sandpack>
|
||||
|
||||
```json package.json hidden
|
||||
{
|
||||
"dependencies": {
|
||||
"react": "experimental",
|
||||
"react-dom": "experimental",
|
||||
"react-scripts": "latest"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "react-scripts test --env=jsdom",
|
||||
"eject": "react-scripts eject"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
import { useState, useEffect, useRef } from 'react';
|
||||
import { experimental_useEvent as useEvent } from 'react';
|
||||
import { FadeInAnimation } from './animation.js';
|
||||
import { useEvent } from './useEvent.js';
|
||||
|
||||
function Welcome({ duration }) {
|
||||
const ref = useRef(null);
|
||||
@@ -1351,25 +1367,6 @@ export class FadeInAnimation {
|
||||
}
|
||||
```
|
||||
|
||||
```js useEvent.js
|
||||
import { useRef, useInsertionEffect, useCallback } from 'react';
|
||||
|
||||
// The useEvent API has not yet been added to React,
|
||||
// so this is a temporary shim to make this sandbox work.
|
||||
// You're not expected to write code like this yourself.
|
||||
|
||||
export function useEvent(fn) {
|
||||
const ref = useRef(null);
|
||||
useInsertionEffect(() => {
|
||||
ref.current = fn;
|
||||
}, [fn]);
|
||||
return useCallback((...args) => {
|
||||
const f = ref.current;
|
||||
return f(...args);
|
||||
}, []);
|
||||
}
|
||||
```
|
||||
|
||||
```css
|
||||
label, button { display: block; margin-bottom: 20px; }
|
||||
html, body { min-height: 300px; }
|
||||
@@ -1383,10 +1380,26 @@ Your Effect needs to read the latest value of `duration`, but you don't want it
|
||||
|
||||
<Sandpack>
|
||||
|
||||
```json package.json hidden
|
||||
{
|
||||
"dependencies": {
|
||||
"react": "experimental",
|
||||
"react-dom": "experimental",
|
||||
"react-scripts": "latest"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "react-scripts test --env=jsdom",
|
||||
"eject": "react-scripts eject"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
import { useState, useEffect, useRef } from 'react';
|
||||
import { FadeInAnimation } from './animation.js';
|
||||
import { useEvent } from './useEvent.js';
|
||||
import { experimental_useEvent as useEvent } from 'react';
|
||||
|
||||
function Welcome({ duration }) {
|
||||
const ref = useRef(null);
|
||||
@@ -1479,25 +1492,6 @@ export class FadeInAnimation {
|
||||
}
|
||||
```
|
||||
|
||||
```js useEvent.js
|
||||
import { useRef, useInsertionEffect, useCallback } from 'react';
|
||||
|
||||
// The useEvent API has not yet been added to React,
|
||||
// so this is a temporary shim to make this sandbox work.
|
||||
// You're not expected to write code like this yourself.
|
||||
|
||||
export function useEvent(fn) {
|
||||
const ref = useRef(null);
|
||||
useInsertionEffect(() => {
|
||||
ref.current = fn;
|
||||
}, [fn]);
|
||||
return useCallback((...args) => {
|
||||
const f = ref.current;
|
||||
return f(...args);
|
||||
}, []);
|
||||
}
|
||||
```
|
||||
|
||||
```css
|
||||
label, button { display: block; margin-bottom: 20px; }
|
||||
html, body { min-height: 300px; }
|
||||
@@ -1825,8 +1819,8 @@ Another of these functions only exists to pass some state to an imported API met
|
||||
```json package.json hidden
|
||||
{
|
||||
"dependencies": {
|
||||
"react": "latest",
|
||||
"react-dom": "latest",
|
||||
"react": "experimental",
|
||||
"react-dom": "experimental",
|
||||
"react-scripts": "latest",
|
||||
"toastify-js": "1.12.0"
|
||||
},
|
||||
@@ -1907,7 +1901,7 @@ export default function App() {
|
||||
|
||||
```js ChatRoom.js active
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useEvent } from './useEvent.js';
|
||||
import { experimental_useEvent as useEvent } from 'react';
|
||||
|
||||
export default function ChatRoom({ roomId, createConnection, onMessage }) {
|
||||
useEffect(() => {
|
||||
@@ -2023,25 +2017,6 @@ export function showNotification(message, theme) {
|
||||
}
|
||||
```
|
||||
|
||||
```js useEvent.js
|
||||
import { useRef, useInsertionEffect, useCallback } from 'react';
|
||||
|
||||
// The useEvent API has not yet been added to React,
|
||||
// so this is a temporary shim to make this sandbox work.
|
||||
// You're not expected to write code like this yourself.
|
||||
|
||||
export function useEvent(fn) {
|
||||
const ref = useRef(null);
|
||||
useInsertionEffect(() => {
|
||||
ref.current = fn;
|
||||
}, [fn]);
|
||||
return useCallback((...args) => {
|
||||
const f = ref.current;
|
||||
return f(...args);
|
||||
}, []);
|
||||
}
|
||||
```
|
||||
|
||||
```css
|
||||
label, button { display: block; margin-bottom: 5px; }
|
||||
```
|
||||
@@ -2139,8 +2114,8 @@ As a result, the chat re-connects only when something meaningful (`roomId` or `i
|
||||
```json package.json hidden
|
||||
{
|
||||
"dependencies": {
|
||||
"react": "latest",
|
||||
"react-dom": "latest",
|
||||
"react": "experimental",
|
||||
"react-dom": "experimental",
|
||||
"react-scripts": "latest",
|
||||
"toastify-js": "1.12.0"
|
||||
},
|
||||
@@ -2208,7 +2183,7 @@ export default function App() {
|
||||
|
||||
```js ChatRoom.js active
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useEvent } from './useEvent.js';
|
||||
import { experimental_useEvent as useEvent } from 'react';
|
||||
import {
|
||||
createEncryptedConnection,
|
||||
createUnencryptedConnection,
|
||||
@@ -2342,25 +2317,6 @@ export function showNotification(message, theme) {
|
||||
}
|
||||
```
|
||||
|
||||
```js useEvent.js
|
||||
import { useRef, useInsertionEffect, useCallback } from 'react';
|
||||
|
||||
// The useEvent API has not yet been added to React,
|
||||
// so this is a temporary shim to make this sandbox work.
|
||||
// You're not expected to write code like this yourself.
|
||||
|
||||
export function useEvent(fn) {
|
||||
const ref = useRef(null);
|
||||
useInsertionEffect(() => {
|
||||
ref.current = fn;
|
||||
}, [fn]);
|
||||
return useCallback((...args) => {
|
||||
const f = ref.current;
|
||||
return f(...args);
|
||||
}, []);
|
||||
}
|
||||
```
|
||||
|
||||
```css
|
||||
label, button { display: block; margin-bottom: 5px; }
|
||||
```
|
||||
|
||||
@@ -985,7 +985,7 @@ export default function ChatRoom({ roomId }) {
|
||||
|
||||
```js useChatRoom.js
|
||||
import { useEffect } from 'react';
|
||||
import { useEvent } from './useEvent.js';
|
||||
import { experimental_useEvent as useEvent } from 'react';
|
||||
import { createConnection } from './chat.js';
|
||||
|
||||
export function useChatRoom({ serverUrl, roomId, onReceiveMessage }) {
|
||||
@@ -1006,25 +1006,6 @@ export function useChatRoom({ serverUrl, roomId, onReceiveMessage }) {
|
||||
}
|
||||
```
|
||||
|
||||
```js useEvent.js
|
||||
import { useRef, useInsertionEffect, useCallback } from 'react';
|
||||
|
||||
// The useEvent API has not yet been added to React,
|
||||
// so this is a temporary shim to make this sandbox work.
|
||||
// You're not expected to write code like this yourself.
|
||||
|
||||
export function useEvent(fn) {
|
||||
const ref = useRef(null);
|
||||
useInsertionEffect(() => {
|
||||
ref.current = fn;
|
||||
}, [fn]);
|
||||
return useCallback((...args) => {
|
||||
const f = ref.current;
|
||||
return f(...args);
|
||||
}, []);
|
||||
}
|
||||
```
|
||||
|
||||
```js chat.js
|
||||
export function createConnection({ serverUrl, roomId }) {
|
||||
// A real implementation would actually connect to the server
|
||||
@@ -1089,8 +1070,8 @@ export function showNotification(message, theme = 'dark') {
|
||||
```json package.json hidden
|
||||
{
|
||||
"dependencies": {
|
||||
"react": "latest",
|
||||
"react-dom": "latest",
|
||||
"react": "experimental",
|
||||
"react-dom": "experimental",
|
||||
"react-scripts": "latest",
|
||||
"toastify-js": "1.12.0"
|
||||
},
|
||||
@@ -1660,7 +1641,7 @@ export default function App() {
|
||||
|
||||
```js useFadeIn.js active
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useEvent } from './useEvent.js';
|
||||
import { experimental_useEvent as useEvent } from 'react';
|
||||
|
||||
export function useFadeIn(ref, duration) {
|
||||
const [isRunning, setIsRunning] = useState(true);
|
||||
@@ -1696,25 +1677,6 @@ function useAnimationLoop(isRunning, drawFrame) {
|
||||
}
|
||||
```
|
||||
|
||||
```js useEvent.js
|
||||
import { useRef, useInsertionEffect, useCallback } from 'react';
|
||||
|
||||
// The useEvent API has not yet been added to React,
|
||||
// so this is a temporary shim to make this sandbox work.
|
||||
// You're not expected to write code like this yourself.
|
||||
|
||||
export function useEvent(fn) {
|
||||
const ref = useRef(null);
|
||||
useInsertionEffect(() => {
|
||||
ref.current = fn;
|
||||
}, [fn]);
|
||||
return useCallback((...args) => {
|
||||
const f = ref.current;
|
||||
return f(...args);
|
||||
}, []);
|
||||
}
|
||||
```
|
||||
|
||||
```css
|
||||
label, button { display: block; margin-bottom: 20px; }
|
||||
html, body { min-height: 300px; }
|
||||
@@ -1728,6 +1690,22 @@ html, body { min-height: 300px; }
|
||||
}
|
||||
```
|
||||
|
||||
```json package.json hidden
|
||||
{
|
||||
"dependencies": {
|
||||
"react": "experimental",
|
||||
"react-dom": "experimental",
|
||||
"react-scripts": "latest"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "react-scripts test --env=jsdom",
|
||||
"eject": "react-scripts eject"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</Sandpack>
|
||||
|
||||
However, you didn't *have to* do that. As with regular functions, ultimately you decide where to draw the boundaries between different parts of your code. For example, you could also take a very different approach. Instead of keeping the logic in the Effect, you could move most of the imperative logic inside a JavaScript [class:](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes)
|
||||
@@ -2202,6 +2180,22 @@ It looks like your `useInterval` Hook accepts an event listener as an argument.
|
||||
|
||||
<Sandpack>
|
||||
|
||||
```json package.json hidden
|
||||
{
|
||||
"dependencies": {
|
||||
"react": "experimental",
|
||||
"react-dom": "experimental",
|
||||
"react-scripts": "latest"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "react-scripts test --env=jsdom",
|
||||
"eject": "react-scripts eject"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
import { useCounter } from './useCounter.js';
|
||||
import { useInterval } from './useInterval.js';
|
||||
@@ -2233,7 +2227,7 @@ export function useCounter(delay) {
|
||||
|
||||
```js useInterval.js
|
||||
import { useEffect } from 'react';
|
||||
import { useEvent } from './useEvent.js';
|
||||
import { experimental_useEvent as useEvent } from 'react';
|
||||
|
||||
export function useInterval(onTick, delay) {
|
||||
useEffect(() => {
|
||||
@@ -2245,25 +2239,6 @@ export function useInterval(onTick, delay) {
|
||||
}
|
||||
```
|
||||
|
||||
```js useEvent.js
|
||||
import { useRef, useInsertionEffect, useCallback } from 'react';
|
||||
|
||||
// The useEvent API has not yet been added to React,
|
||||
// so this is a temporary shim to make this sandbox work.
|
||||
// You're not expected to write code like this yourself.
|
||||
|
||||
export function useEvent(fn) {
|
||||
const ref = useRef(null);
|
||||
useInsertionEffect(() => {
|
||||
ref.current = fn;
|
||||
}, [fn]);
|
||||
return useCallback((...args) => {
|
||||
const f = ref.current;
|
||||
return f(...args);
|
||||
}, []);
|
||||
}
|
||||
```
|
||||
|
||||
</Sandpack>
|
||||
|
||||
<Solution>
|
||||
@@ -2276,6 +2251,23 @@ With this change, both intervals work as expected and don't interfere with each
|
||||
|
||||
<Sandpack>
|
||||
|
||||
```json package.json hidden
|
||||
{
|
||||
"dependencies": {
|
||||
"react": "experimental",
|
||||
"react-dom": "experimental",
|
||||
"react-scripts": "latest"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "react-scripts test --env=jsdom",
|
||||
"eject": "react-scripts eject"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
```js
|
||||
import { useCounter } from './useCounter.js';
|
||||
import { useInterval } from './useInterval.js';
|
||||
@@ -2307,7 +2299,7 @@ export function useCounter(delay) {
|
||||
|
||||
```js useInterval.js active
|
||||
import { useEffect } from 'react';
|
||||
import { useEvent } from './useEvent.js';
|
||||
import { experimental_useEvent as useEvent } from 'react';
|
||||
|
||||
export function useInterval(callback, delay) {
|
||||
const onTick = useEvent(callback);
|
||||
@@ -2318,25 +2310,6 @@ export function useInterval(callback, delay) {
|
||||
}
|
||||
```
|
||||
|
||||
```js useEvent.js
|
||||
import { useRef, useInsertionEffect, useCallback } from 'react';
|
||||
|
||||
// The useEvent API has not yet been added to React,
|
||||
// so this is a temporary shim to make this sandbox work.
|
||||
// You're not expected to write code like this yourself.
|
||||
|
||||
export function useEvent(fn) {
|
||||
const ref = useRef(null);
|
||||
useInsertionEffect(() => {
|
||||
ref.current = fn;
|
||||
}, [fn]);
|
||||
return useCallback((...args) => {
|
||||
const f = ref.current;
|
||||
return f(...args);
|
||||
}, []);
|
||||
}
|
||||
```
|
||||
|
||||
</Sandpack>
|
||||
|
||||
</Solution>
|
||||
|
||||
@@ -448,8 +448,8 @@ Verify that the new behavior works as you would expect:
|
||||
```json package.json hidden
|
||||
{
|
||||
"dependencies": {
|
||||
"react": "latest",
|
||||
"react-dom": "latest",
|
||||
"react": "experimental",
|
||||
"react-dom": "experimental",
|
||||
"react-scripts": "latest",
|
||||
"toastify-js": "1.12.0"
|
||||
},
|
||||
@@ -464,7 +464,7 @@ Verify that the new behavior works as you would expect:
|
||||
|
||||
```js
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useEvent } from './useEvent.js';
|
||||
import { experimental_useEvent as useEvent } from 'react';
|
||||
import { createConnection, sendMessage } from './chat.js';
|
||||
import { showNotification } from './notifications.js';
|
||||
|
||||
@@ -568,25 +568,6 @@ export function showNotification(message, theme) {
|
||||
}
|
||||
```
|
||||
|
||||
```js useEvent.js
|
||||
import { useRef, useInsertionEffect, useCallback } from 'react';
|
||||
|
||||
// The useEvent API has not yet been added to React,
|
||||
// so this is a temporary shim to make this sandbox work.
|
||||
// You're not expected to write code like this yourself.
|
||||
|
||||
export function useEvent(fn) {
|
||||
const ref = useRef(null);
|
||||
useInsertionEffect(() => {
|
||||
ref.current = fn;
|
||||
}, [fn]);
|
||||
return useCallback((...args) => {
|
||||
const f = ref.current;
|
||||
return f(...args);
|
||||
}, []);
|
||||
}
|
||||
```
|
||||
|
||||
```css
|
||||
label { display: block; margin-top: 10px; }
|
||||
```
|
||||
@@ -817,7 +798,7 @@ With `useEvent`, there is no need to "lie" to the linter, and the code works as
|
||||
|
||||
```js
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useEvent } from './useEvent.js';
|
||||
import { experimental_useEvent as useEvent } from 'react';
|
||||
|
||||
export default function App() {
|
||||
const [position, setPosition] = useState({ x: 0, y: 0 });
|
||||
@@ -861,25 +842,6 @@ export default function App() {
|
||||
}
|
||||
```
|
||||
|
||||
```js useEvent.js
|
||||
import { useRef, useInsertionEffect, useCallback } from 'react';
|
||||
|
||||
// The useEvent API has not yet been added to React,
|
||||
// so this is a temporary shim to make this sandbox work.
|
||||
// You're not expected to write code like this yourself.
|
||||
|
||||
export function useEvent(fn) {
|
||||
const ref = useRef(null);
|
||||
useInsertionEffect(() => {
|
||||
ref.current = fn;
|
||||
}, [fn]);
|
||||
return useCallback((...args) => {
|
||||
const f = ref.current;
|
||||
return f(...args);
|
||||
}, []);
|
||||
}
|
||||
```
|
||||
|
||||
```css
|
||||
body {
|
||||
height: 200px;
|
||||
@@ -1106,9 +1068,25 @@ It seems like the Effect which sets up the timer "reacts" to the `increment` val
|
||||
|
||||
<Sandpack>
|
||||
|
||||
```json package.json hidden
|
||||
{
|
||||
"dependencies": {
|
||||
"react": "experimental",
|
||||
"react-dom": "experimental",
|
||||
"react-scripts": "latest"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "react-scripts test --env=jsdom",
|
||||
"eject": "react-scripts eject"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useEvent } from './useEvent.js';
|
||||
import { experimental_useEvent as useEvent } from 'react';
|
||||
|
||||
export default function Timer() {
|
||||
const [count, setCount] = useState(0);
|
||||
@@ -1145,25 +1123,6 @@ export default function Timer() {
|
||||
}
|
||||
```
|
||||
|
||||
```js useEvent.js
|
||||
import { useRef, useInsertionEffect, useCallback } from 'react';
|
||||
|
||||
// The useEvent API has not yet been added to React,
|
||||
// so this is a temporary shim to make this sandbox work.
|
||||
// You're not expected to write code like this yourself.
|
||||
|
||||
export function useEvent(fn) {
|
||||
const ref = useRef(null);
|
||||
useInsertionEffect(() => {
|
||||
ref.current = fn;
|
||||
}, [fn]);
|
||||
return useCallback((...args) => {
|
||||
const f = ref.current;
|
||||
return f(...args);
|
||||
}, []);
|
||||
}
|
||||
```
|
||||
|
||||
```css
|
||||
button { margin: 10px; }
|
||||
```
|
||||
@@ -1178,9 +1137,25 @@ To solve the issue, extract an `onTick` Event function from the Effect:
|
||||
|
||||
<Sandpack>
|
||||
|
||||
```json package.json hidden
|
||||
{
|
||||
"dependencies": {
|
||||
"react": "experimental",
|
||||
"react-dom": "experimental",
|
||||
"react-scripts": "latest"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "react-scripts test --env=jsdom",
|
||||
"eject": "react-scripts eject"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useEvent } from './useEvent.js';
|
||||
import { experimental_useEvent as useEvent } from 'react';
|
||||
|
||||
export default function Timer() {
|
||||
const [count, setCount] = useState(0);
|
||||
@@ -1222,25 +1197,6 @@ export default function Timer() {
|
||||
```
|
||||
|
||||
|
||||
```js useEvent.js
|
||||
import { useRef, useInsertionEffect, useCallback } from 'react';
|
||||
|
||||
// The useEvent API has not yet been added to React,
|
||||
// so this is a temporary shim to make this sandbox work.
|
||||
// You're not expected to write code like this yourself.
|
||||
|
||||
export function useEvent(fn) {
|
||||
const ref = useRef(null);
|
||||
useInsertionEffect(() => {
|
||||
ref.current = fn;
|
||||
}, [fn]);
|
||||
return useCallback((...args) => {
|
||||
const f = ref.current;
|
||||
return f(...args);
|
||||
}, []);
|
||||
}
|
||||
```
|
||||
|
||||
```css
|
||||
button { margin: 10px; }
|
||||
```
|
||||
@@ -1263,9 +1219,25 @@ Code inside Event functions is not reactive. Are there cases in which you would
|
||||
|
||||
<Sandpack>
|
||||
|
||||
```json package.json hidden
|
||||
{
|
||||
"dependencies": {
|
||||
"react": "experimental",
|
||||
"react-dom": "experimental",
|
||||
"react-scripts": "latest"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "react-scripts test --env=jsdom",
|
||||
"eject": "react-scripts eject"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useEvent } from './useEvent.js';
|
||||
import { experimental_useEvent as useEvent } from 'react';
|
||||
|
||||
export default function Timer() {
|
||||
const [count, setCount] = useState(0);
|
||||
@@ -1322,25 +1294,6 @@ export default function Timer() {
|
||||
```
|
||||
|
||||
|
||||
```js useEvent.js
|
||||
import { useRef, useInsertionEffect, useCallback } from 'react';
|
||||
|
||||
// The useEvent API has not yet been added to React,
|
||||
// so this is a temporary shim to make this sandbox work.
|
||||
// You're not expected to write code like this yourself.
|
||||
|
||||
export function useEvent(fn) {
|
||||
const ref = useRef(null);
|
||||
useInsertionEffect(() => {
|
||||
ref.current = fn;
|
||||
}, [fn]);
|
||||
return useCallback((...args) => {
|
||||
const f = ref.current;
|
||||
return f(...args);
|
||||
}, []);
|
||||
}
|
||||
```
|
||||
|
||||
```css
|
||||
button { margin: 10px; }
|
||||
```
|
||||
@@ -1353,9 +1306,25 @@ The problem with the above example is that it extracted an Event function called
|
||||
|
||||
<Sandpack>
|
||||
|
||||
```json package.json hidden
|
||||
{
|
||||
"dependencies": {
|
||||
"react": "experimental",
|
||||
"react-dom": "experimental",
|
||||
"react-scripts": "latest"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "react-scripts test --env=jsdom",
|
||||
"eject": "react-scripts eject"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useEvent } from './useEvent.js';
|
||||
import { experimental_useEvent as useEvent } from 'react';
|
||||
|
||||
export default function Timer() {
|
||||
const [count, setCount] = useState(0);
|
||||
@@ -1407,25 +1376,6 @@ export default function Timer() {
|
||||
}
|
||||
```
|
||||
|
||||
```js useEvent.js
|
||||
import { useRef, useInsertionEffect, useCallback } from 'react';
|
||||
|
||||
// The useEvent API has not yet been added to React,
|
||||
// so this is a temporary shim to make this sandbox work.
|
||||
// You're not expected to write code like this yourself.
|
||||
|
||||
export function useEvent(fn) {
|
||||
const ref = useRef(null);
|
||||
useInsertionEffect(() => {
|
||||
ref.current = fn;
|
||||
}, [fn]);
|
||||
return useCallback((...args) => {
|
||||
const f = ref.current;
|
||||
return f(...args);
|
||||
}, []);
|
||||
}
|
||||
```
|
||||
|
||||
```css
|
||||
button { margin: 10px; }
|
||||
```
|
||||
@@ -1455,8 +1405,8 @@ Your Effect knows which room it connected to. Is there any information that you
|
||||
```json package.json hidden
|
||||
{
|
||||
"dependencies": {
|
||||
"react": "latest",
|
||||
"react-dom": "latest",
|
||||
"react": "experimental",
|
||||
"react-dom": "experimental",
|
||||
"react-scripts": "latest",
|
||||
"toastify-js": "1.12.0"
|
||||
},
|
||||
@@ -1471,7 +1421,7 @@ Your Effect knows which room it connected to. Is there any information that you
|
||||
|
||||
```js
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useEvent } from './useEvent.js';
|
||||
import { experimental_useEvent as useEvent } from 'react';
|
||||
import { createConnection, sendMessage } from './chat.js';
|
||||
import { showNotification } from './notifications.js';
|
||||
|
||||
@@ -1577,25 +1527,6 @@ export function showNotification(message, theme) {
|
||||
}
|
||||
```
|
||||
|
||||
```js useEvent.js
|
||||
import { useRef, useInsertionEffect, useCallback } from 'react';
|
||||
|
||||
// The useEvent API has not yet been added to React,
|
||||
// so this is a temporary shim to make this sandbox work.
|
||||
// You're not expected to write code like this yourself.
|
||||
|
||||
export function useEvent(fn) {
|
||||
const ref = useRef(null);
|
||||
useInsertionEffect(() => {
|
||||
ref.current = fn;
|
||||
}, [fn]);
|
||||
return useCallback((...args) => {
|
||||
const f = ref.current;
|
||||
return f(...args);
|
||||
}, []);
|
||||
}
|
||||
```
|
||||
|
||||
```css
|
||||
label { display: block; margin-top: 10px; }
|
||||
```
|
||||
@@ -1615,8 +1546,8 @@ To fix the issue, instead of reading the *latest* `roomId` inside the Event func
|
||||
```json package.json hidden
|
||||
{
|
||||
"dependencies": {
|
||||
"react": "latest",
|
||||
"react-dom": "latest",
|
||||
"react": "experimental",
|
||||
"react-dom": "experimental",
|
||||
"react-scripts": "latest",
|
||||
"toastify-js": "1.12.0"
|
||||
},
|
||||
@@ -1631,7 +1562,7 @@ To fix the issue, instead of reading the *latest* `roomId` inside the Event func
|
||||
|
||||
```js
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useEvent } from './useEvent.js';
|
||||
import { experimental_useEvent as useEvent } from 'react';
|
||||
import { createConnection, sendMessage } from './chat.js';
|
||||
import { showNotification } from './notifications.js';
|
||||
|
||||
@@ -1737,25 +1668,6 @@ export function showNotification(message, theme) {
|
||||
}
|
||||
```
|
||||
|
||||
```js useEvent.js
|
||||
import { useRef, useInsertionEffect, useCallback } from 'react';
|
||||
|
||||
// The useEvent API has not yet been added to React,
|
||||
// so this is a temporary shim to make this sandbox work.
|
||||
// You're not expected to write code like this yourself.
|
||||
|
||||
export function useEvent(fn) {
|
||||
const ref = useRef(null);
|
||||
useInsertionEffect(() => {
|
||||
ref.current = fn;
|
||||
}, [fn]);
|
||||
return useCallback((...args) => {
|
||||
const f = ref.current;
|
||||
return f(...args);
|
||||
}, []);
|
||||
}
|
||||
```
|
||||
|
||||
```css
|
||||
label { display: block; margin-top: 10px; }
|
||||
```
|
||||
@@ -1771,8 +1683,8 @@ To solve the additional challenge, save the notification timeout ID and clear it
|
||||
```json package.json hidden
|
||||
{
|
||||
"dependencies": {
|
||||
"react": "latest",
|
||||
"react-dom": "latest",
|
||||
"react": "experimental",
|
||||
"react-dom": "experimental",
|
||||
"react-scripts": "latest",
|
||||
"toastify-js": "1.12.0"
|
||||
},
|
||||
@@ -1787,7 +1699,7 @@ To solve the additional challenge, save the notification timeout ID and clear it
|
||||
|
||||
```js
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useEvent } from './useEvent.js';
|
||||
import { experimental_useEvent as useEvent } from 'react';
|
||||
import { createConnection, sendMessage } from './chat.js';
|
||||
import { showNotification } from './notifications.js';
|
||||
|
||||
@@ -1899,25 +1811,6 @@ export function showNotification(message, theme) {
|
||||
}
|
||||
```
|
||||
|
||||
```js useEvent.js
|
||||
import { useRef, useInsertionEffect, useCallback } from 'react';
|
||||
|
||||
// The useEvent API has not yet been added to React,
|
||||
// so this is a temporary shim to make this sandbox work.
|
||||
// You're not expected to write code like this yourself.
|
||||
|
||||
export function useEvent(fn) {
|
||||
const ref = useRef(null);
|
||||
useInsertionEffect(() => {
|
||||
ref.current = fn;
|
||||
}, [fn]);
|
||||
return useCallback((...args) => {
|
||||
const f = ref.current;
|
||||
return f(...args);
|
||||
}, []);
|
||||
}
|
||||
```
|
||||
|
||||
```css
|
||||
label { display: block; margin-top: 10px; }
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user