Dead Simple Chat offers Javascript Chat API and SDK to add in-app chat to your React applications in minutes. Dead Simple Chat is a highly customizable chat solution and can be used for any chat use case.
The useSyncExternalStore
is a custom hook available in React 18, that lets you subscribe to an external store and update your React component when the external store updates.
It is especially useful in subscribing to external stores that are not built on top of React state management.
useSyncExternalStore
API
You should call the useSyncExternalStore
method at the top level of your component.
import { useSyncExternalStore } from 'react';
import { myStore } from "./mystore.js";
function MyComponent() {
const data = useSyncExternalStore(myStore.subscribe, myStore.getSnapshot);
// Rest of the component ...
}
The useSyncExternalStore
method accepts two parameters:
subscribe
- The subscribe method should subscribe to the store updates, and it should return a function to unsubscribe from the store update. We will look at an example below of how to create a store to use withuseSyncExternalStore
.getSnapshot
- Method would return a snapshot of data from the store.
Basic Example using useSyncExternalStore
Let's build a very basic store to understand the useSyncExternalStore
API.
Our store would store just a count and would provide a method to increment and decrement the count.
The count
is used to store our counter and the subscribers
array store the list of subscriber methods.
The read()
method is the getSnapshot()
method that fetches the snapshot of the store.
The subscribe(callback)
method is used to subscribe to the store, and it is in the format that is required by the useSyncExternalStore
.
We are storing the callback
method in a Set, and each time the count is updated we are iterating over all the callback
methods and calling them.
Once the callback
is called, the useSyncExternalStore
will call the read()
method to fetch the value from the store.
Now, let's build our component to use the store, we will update our App.js
component to use our newly created store.
As you can see, when we increment or decrement the count, the component automatically updates to reflect the updated count value.
Building a Todo App using useSyncExternalStore
Let's basic a Todo application, first, we will create a store.js
file that will store our todos:
In our store.js
file we have created an array called as todos
to store the list of todos.
Next similar to our previous example we have created a variable called as subscribers
that contains an array of callback functions that have subscribed to the store.
We would have to call these functions whenever the value of the store is updated.
In the addTodo
the method you might have noticed that we are not using push
method to add a todo to the todos
array because by doing this React will not detect a change and reload the component because of immutability in React.
Hence you should remember not to update the todo
array in place, rather creates a new array when adding a todo.
We are doing the same thing in the toggleTodo
method, rather than updating the todo by index in the toggleTodo
method we are creating a new todos
array using the map
method that contains the updated value.
Next, we will create a TodoList.js
file to hold our TodoList
component, the TodoList
component will use the useSyncExternalStore
subscribe to the store and update its UI when a new Todo is added.
In our TodoList
component we are fetching the list of todos
from the store using the useSyncExternalStore
hook.
We are also calling the toggleTodo
method when the todo is checked, and when we will run this code you will see that the UI will be updated.
Next, we will create a AddTodoForm
component, to add a new Todo, here is the code for our AddTodoForm
component:
The AddTodoForm
component is also very basic, here we are importing our store, and using the useState
method from react.
We have created a state variable called as text
that will store the text for our todo.
Next, we created two event listeners, we have added an onChange
event listener on the <input />
tag, when the value of the input tag changes we are updating the state variable called as text
with value typed on the input tag.
The second event listener we have added to the form, we have added an onSubmit
event listener when the form is submitted by pressing the "Add Todo" button.
In the onSubmit
event listener we are calling the handleSubmit
method, this method, this method will call the addTodo
method of our Store.
When a todo is added from this component, as we are using useSyncExternalStore
hook in our TodoList
component, the TodoList
the component will also update automatically to display the newly added todo.
Now, lets finally build our App.js
component, and import our AddTodoForm
and TodoList
components:
Here is the demo of our application, as you can see in the video below the Component UI is updating automatically as the data in the store updates.
Improving code by using custom hook
We can improve our code further, but extracting the call toe useSyncExternalStore
in a custom hook and then simply using the custom hook in our components.
We will update our store.js
file to include the code for our custom hook called as useTodo
Then we will update our TodoList.js
file to include our custom useTodo
hook:
When to use useSyncExternalStore
?
It is recommended that you use React's built-in state management hooks like useState
and useReducer
to manage the state.
But there are some scenarios where useSyncExternalStore
make sense:
- Integrating Reacting with an existing non-react codebase
If you have a non-react codebase that uses some type of external store, and you want to integrate your react application with the existing store then in that case you can build a wrapper around the store that is in line with the useSyncExternalStore
API to seamlessly integrate the store with the React application.
- Subscribing to browser APIs
You can use it to subscribe to browser APIs, like web push notifications or the navigator.onLine
property.
React official documentation has a good example explaining how the use the navigator.onLine
property with useSyncExternalStore
hook.
You can read the doc here.
Dead Simple Chat offers Javascript Chat API and SDK to add in-app chat to your React applications in minutes. Dead Simple Chat is a highly customizable chat solution and can be used for any chat use case.
You might be interested in some of our other articles
- React useDeferredValue
- React Suspense for Data Fetching with Axios in React 18
- React useMemo Vs useCallback
- React useState: The Complete guide
Conclusion
In this blog post, we have learned how to use useSyncExternalStore
in our code to sync with an external store in React.
We should use useState
and useReducer
hooks in our code whenever possible, but in a few cases where it is not possible to use the useState
and useReducer
we can use the useSyncExternalStore
to sync our react components with an external store.