Last active
October 10, 2023 03:17
-
-
Save kpunith8/2bb2b62620b6cf78f71d4164a8ecb420 to your computer and use it in GitHub Desktop.
Using query and route params with useContext() Hook
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, {useState} from 'react' | |
import RouteContext, {EMPTY_ROUTE} from './route-context' | |
const App = props => { | |
const [route, setRoute] = useState(EMPTY_ROUTE) | |
useEffect(() => { | |
// Logic to update the setRoute() based on the current route | |
// route object has params and query keys, update them accordingly | |
// or pass setRoute setter as vlaue to th Provider | |
// <RouteContext.Provider value={{route, setRoute}}>, whenever you call setRoute in | |
// a child component it will re-render the app depending on route params (only rerenders the part of the UI, which | |
// makes the call to specific API based on useEffect) | |
}, []) | |
return ( | |
<RouteContext.Provider value={route}> | |
<Layout {props...} /> | |
</RouteContext.Provider> | |
) | |
} | |
export default App |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { useContext, useEffect, useState } from "react"; | |
const EMPTY_ROUTE = { params: {}, query: {} }; | |
const UserContext = React.createContext(); | |
const UserInfo = () => { | |
const { route, setRoute } = useContext(UserContext); | |
return ( | |
<> | |
<pre>{JSON.stringify(route, null, 2)}</pre> | |
<button | |
onClick={() => | |
// Try removing the name property on query and see how it re-renders the UI | |
setRoute({ params: "1", query: { id: 1, name: "Punith" } }) | |
} | |
> | |
New User | |
</button> | |
</> | |
); | |
}; | |
const UserDetails = () => { | |
const [userDetails, setUserDetails] = useState(""); | |
const { route } = useContext(UserContext); | |
// This useEffect can invoke any async call, including calling an websocket | |
// so that all the users using this UI will be updated. | |
useEffect(() => { | |
console.log("set user details"); | |
// This useEffect() will re-run only if you update route.query.name | |
// property in UserInfo's onClick listener. Remove updating "name" | |
// property on query key to see the re-rendering in action | |
setUserDetails(route.query.name); | |
}, [route.query.name]); | |
return ( | |
<> | |
<div>{userDetails}</div> | |
</> | |
); | |
}; | |
const UseContextSample = (props) => { | |
const [route, setRoute] = useState(EMPTY_ROUTE); | |
return ( | |
<UserContext.Provider value={{ route, setRoute }}> | |
<UserInfo {...props} /> | |
<UserDetails /> | |
</UserContext.Provider> | |
); | |
}; | |
export default UseContextSample; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, {useContext} from 'react' | |
import RouteContext from './route-context' | |
// actions coming from where the useService() and actions are defined as per this ariticle | |
// https://pktechblog.netlify.app/blog/post/how-to-manage-complex-ui-state-with-use-reducer | |
const Layout = ({actions} ...props) => { | |
const route = useContext(RouteContext) | |
useEffect(() => { | |
// Call the appropriate action to fetch the data whenever there is a changes to | |
// query or param | |
// Whenever the readUserInfo() updates the state we can re-render the UI | |
// to all the users or this Layout or any child component. | |
// It only make the call to service actions only if there is a change to query or param | |
// I'm assuming that we are receving query paramsfrom libraries called react-router-dom | |
// It can be any random object that controls the data fetching or mimics the user action. | |
actions.readUserInfo({query: route.query, params: route.params}) | |
}, [route.query, route.params]) | |
render ( | |
// Because we are using context API, we can make change in any | |
// child component, pass down the actions if you want to make a API | |
// call or data fetch from anywhere down the DOM tree | |
<AnotherComponent {...{actions, ...props}}/> | |
) | |
} | |
export default Layout |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react' | |
export const EMPTY_ROUTE = {params: {}, query: {}} | |
const RouteContext = React.createContext(EMPTY_ROUTE) | |
export default RouteContext |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Added working example, complete-working-sample.js please refer and implement as required