Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save technolaaji/4c77f39663c67b783247b6e842bc2ec7 to your computer and use it in GitHub Desktop.
Save technolaaji/4c77f39663c67b783247b6e842bc2ec7 to your computer and use it in GitHub Desktop.
React Hooks - Redux Example and Context Example for Hooks
Here is an small example of the issues I face when using Redux and Redux Toolkit with other libraries hooks
keep in mind that it is something I have been facing for quite some time, if you have a better solution then go ahead I am all ears here (really)
maybe I am not using Redux properly or misusing it or there might be a better way of handling this situation but I am up for feedback and suggestions
hooks like useNavigate from @reach/router or toast from react-toastify expect to be found within a Provider (which is expected)
my coding pattern is that when I write my dispatch functions, I tend to write them away from the component and import it as a single function
that perform everything under the hood, keeping my components more readable and clean to look at
typically I would use useDispatch from react-redux and create a dispatch function and pass it as a reference inside of that function
the example that I am going to provide is a function that updates your availability and sends a toast when it successfully updates
first I will create a slice (using Redux Toolkit) so the slice will be like the following:
const availableSlice = createSlice(
name: 'Available Slice',
initialState: {
status: true
},
reducer: {
update(state,action){
state.status = action.payload
}
}
);
then I created my useDispatch and toast hook inside of my component
consider that I have already configured my http library of choice with all the authorization configuration and interceptors (here it is axios)
now that function that will dispatch this action, I pass the dispatch and the toast as a reference in the function so like this
const updateAvailability = async(dispatch, toast) => {
const response = await axios.post('/user/availability');
if(response.data.statusCode){
toast('Availability updated successfully!');
dispatch(availableSlice.actions.update(response.data.status));
}
else {
toast('Something wrong happened, please try again later');
}
}
inside of my component I would call this function and use it
// inside component of choice
import { toast } from 'react-toastify';
import { useDispatch } from 'react-redux';
const dispatch = useDispatch();
const triggerUpdateAvailability = async () => {
// the function we created earlier
await updateAvailability(dispatch, toast);
}
Another thing I have been doing that I feel that is quite of a hack is importing the store and dispatching from it directly
so the previous will look like this
const updateAvailability = async(toast) => {
const response = await axios.post('/user/availability');
if(response.data.statusCode){
toast('Availability updated successfully!');
store.dispatch(availableSlice.actions.update(response.data.status));
}
else {
toast('Something wrong happened, please try again later');
}
}
I have tried the store.dispatch and it served me well in some projects but I feel it is a bit hacky so I prevent using it but it saves me from importing the dispatch hook everytime I need to dispatch
the context version is a bit smoother and easier for me in my perspective so it looks more like this:
import React, {useContext, createContext, useState } from 'react'
import axios from 'axios'
import { toast } from 'react-toastify'
const AvailableContext = createContext(null);
const AvailableProvider = ({ children }) => {
const [availabilty, updateAvailabilty] = useState(true);
const update = async () => {
const response = await axios.post('/user/availability');
if(response.data.statusCode){
toast('Availability updated successfully!');
updateAvailabilty(response.data.status);
}
else {
toast('Something wrong happened, please try again later');
}
}
return <AvailableContext.Provider value={[availabilty, update]}> {children} </AvailableContext>
}
const useUpdateAvailabilty = () => {
const context = useContext(AvailabiltyContext);
if(context === null || context === undefined){
throw new Error('useUpdateAvailabilty must be found within a AvailableProvider');
}
return context;
}
now in my app I just need to import that hook and use it so like this:
const [availabilty, update] = useUpdateAvailabilty();
const triggerUpdateAvailability = async () => {
await update();
}
the context version does require some extra setup but I feel that it is a bit clear and easier to work with other hook functions
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment