Skip to content

fix/7098 useOptimistic document #7109

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 22 additions & 13 deletions src/content/reference/react/useOptimistic.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,9 @@ function AppContainer() {
#### Parameters {/*parameters*/}

* `state`: the value to be returned initially and whenever no action is pending.
* `updateFn(currentState, optimisticValue)`: a function that takes the current state and the optimistic value passed to `addOptimistic` and returns the resulting optimistic state. It must be a pure function. `updateFn` takes in two parameters. The `currentState` and the `optimisticValue`. The return value will be the merged value of the `currentState` and `optimisticValue`.
* `updateFn(currentState, optimisticValue)` (optional but recommended): A pure function that accepts the current state and an `optimisticValue`, returning the resulting optimistic state to be used during the pending action. This function is crucial for merging the current state with the optimistic update. While optional, omitting this function may result in the state remaining unchanged during the async action, as the hook will fall back to returning the initial.

**Note**: Although you can omit `updateFn`, doing so will cause `useOptimistic` to keep the state static during async actions, which might not align with the desired behavior in most scenarios. By providing `updateFn`, you ensure that the state properly reflects optimistic updates while the action is pending.

#### Returns {/*returns*/}

Expand All @@ -65,7 +66,7 @@ function AppContainer() {

### Optimistically updating forms {/*optimistically-updating-with-forms*/}

The `useOptimistic` Hook provides a way to optimistically update the user interface before a background operation, like a network request, completes. In the context of forms, this technique helps to make apps feel more responsive. When a user submits a form, instead of waiting for the server's response to reflect the changes, the interface is immediately updated with the expected outcome.
The `useOptimistic` Hook provides a way to optimistically update the user interface before a background operation, like a network request, completes. In the context of forms, this technique helps to make apps feel more responsive. When a user submits a form, instead of waiting for the server's response to reflect the changes, the interface is immediately updated with the expected outcome, giving the impression of a faster interaction.

For example, when a user types a message into the form and hits the "Send" button, the `useOptimistic` Hook allows the message to immediately appear in the list with a "Sending..." label, even before the message is actually sent to a server. This "optimistic" approach gives the impression of speed and responsiveness. The form then attempts to truly send the message in the background. Once the server confirms the message has been received, the "Sending..." label is removed.

Expand All @@ -77,31 +78,38 @@ import { useOptimistic, useState, useRef } from "react";
import { deliverMessage } from "./actions.js";

function Thread({ messages, sendMessage }) {
const formRef = useRef();
const formRef = useRef(); // Ref to reset the form after submission

// Function to handle form submission
async function formAction(formData) {
addOptimisticMessage(formData.get("message"));
formRef.current.reset();
await sendMessage(formData);
addOptimisticMessage(formData.get("message")); // Add the new message optimistically
formRef.current.reset(); // Reset the form after submission
await sendMessage(formData); // Send the actual message asynchronously
}

// Define the optimistic state and the function to add optimistic messages
const [optimisticMessages, addOptimisticMessage] = useOptimistic(
messages,
messages, // The update function merges the new optimistic message into the current state
(state, newMessage) => [
...state,
{
text: newMessage,
sending: true
sending: true // Mark the message as sending until the async action completes

}
]
);

return (
<>
{/* Render the list of messages, including the optimistic ones */}
{optimisticMessages.map((message, index) => (
<div key={index}>
{message.text}
{!!message.sending && <small> (Sending...)</small>}
</div>
))}
{/* Form to send a new message */}
<form action={formAction} ref={formRef}>
<input type="text" name="message" placeholder="Hello!" />
<button type="submit">Send</button>
Expand All @@ -112,20 +120,21 @@ function Thread({ messages, sendMessage }) {

export default function App() {
const [messages, setMessages] = useState([
{ text: "Hello there!", sending: false, key: 1 }
{ text: "Hello there!", sending: false, key: 1 }// Initial message state
]);
// Function to send the message and update the state when it successfully sends
async function sendMessage(formData) {
const sentMessage = await deliverMessage(formData.get("message"));
setMessages((messages) => [...messages, { text: sentMessage }]);
const sentMessage = await deliverMessage(formData.get("message")); // Simulate sending the message
setMessages((messages) => [...messages, { text: sentMessage }]); // Add the sent message to the state
}
return <Thread messages={messages} sendMessage={sendMessage} />;
}
```

```js src/actions.js
export async function deliverMessage(message) {
await new Promise((res) => setTimeout(res, 1000));
return message;
await new Promise((res) => setTimeout(res, 1000));// Simulate network delay
return message; // Return the message after the delay
}
```

Expand Down
Loading