Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
December 23, 2021 08:21 am GMT

Have you used `flushSync` in React?

In this post we'll discuss about the flushSync utility provided by react-dom.

Let's try and understand what flushSync is and how it can useful through an example.

As always, it's a simple todo example but the point to note here is that the todo container has fixed height and is scrollable.

So, there's our App component that has a todos state and returns a list of todos along with a form.

export default function App() {  const [todos, setTodos] = useState(mockTodos);  const onAdd = (newTask) => {    setTodos([...todos, { id: uuid(), task: newTask }]);  };  return (    <section className="app">      <h1>Todos</h1>      <ul style={{ height: 200, overflowY: "auto" }}>        {todos.map((todo) => (          <li key={todo.id}>{todo.task}</li>        ))}      </ul>      <AddTodo onAdd={onAdd} />    </section>  );}

The AddTodo component is also fairly simple, it just manages the input state and once the form is submitted it calls the onAdd prop with the new todo.

const AddTodo = ({ onAdd }) => {  const [taskInput, setTaskInput] = useState("");  const handleSubmit = (e) => {    e.preventDefault();    if (!taskInput.trim()) return;    setTaskInput("");    onAdd(taskInput.trim());  };  return (    <form onSubmit={handleSubmit}>      <input        type="text"        placeholder="Your Task"        value={taskInput}        onChange={(e) => setTaskInput(e.target.value)}      />      <button>Add Task</button>    </form>  );};

Now that we've an understanding of how our code works, suppose we want to add a functionality where every time a new todo is added, the container is scrolled to its bottom so that the newly added todo is visible to the user.

Think for while and figure out how you would go about implementing this functionality.

Using useEffect hook

So, you might be thinking of using the effect hook. Every time the todos change just scroll the container to the bottom.

useEffect(() => {  listRef.current.scrollTop = listRef.current.scrollHeight;  // listRef is simply a ref attached to the ul}, [todos]);

OR

useEffect(() => {  const lastTodo = listRef.current.lastElementChild;  lastTodo.scrollIntoView();}, [todos]);

Both of these work fine but you might want to you use the useLayoutEffect hook in this situation in case you observe any jitters in scrolling.

But, I would not want to put this in either of these hooks because I feel that more than a side effect, it actually should be a part of the onAdd handler itself. So, let's try and do that.

Scrolling logic inside the handler

If you simply put the scrolling logic inside the handler (as shown below), you would notice that you're not exactly getting the desired results.

const onAdd = (newTask) => {  setTodos([...todos, { id: uuid(), task: newTask }]);  const lastTodo = listRef.current.lastElementChild;  lastTodo.scrollIntoView();};

Because setTodos is not synchronous, what happens is you scroll first and then the todos actually get updated. So, what's in view is not the last todo but second to last.

So, to get it working as expected we would have to make sure that the logic for scrolling runs only after the todos state has been updated. And that's where flushSync comes handy.

Using flushSync

To use flushSync, we need to import it from react-dom: import { flushSync } from "react-dom";

And now we can wrap the setTodos call inside flushSync handler (as shown below).

const onAdd = (newTask) => {  flushSync(() => {    setTodos([...todos, { id: uuid(), task: newTask }]);  });  const lastTodo = listRef.current.lastElementChild;  lastTodo.scrollIntoView();};

Now we have made sure that the state update happens synchronously and the logic for scrolling is executed only after the state has been updated.

That's it for this post, let me know situations where you would want to use flushSync.

Peace


Original Link: https://dev.to/ssmkhrj/have-you-used-flushsync-in-react-4cpo

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To