Created
April 27, 2020 22:51
-
-
Save sangkukbae12/c70a85bfe046987e7c3e359c3bc722f3 to your computer and use it in GitHub Desktop.
react context pattern
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
const MyContext = React.createContext(defaultValue); | |
<MyContext.Provider value={someValue}> | |
const value = useContext(MyContext); | |
// app.js | |
import React, {useState} from 'react'; | |
import Comp1 from './comp1'; | |
import { UserProvider } from './user' | |
import './App.css'; | |
function App() { | |
const [number, setNumber] = useState(0); | |
const changeNumberHandler = () => { | |
setNumber(c => c + 1) | |
} | |
return ( | |
<div className="App"> | |
The Main App Component {number} | |
<UserProvider> {/* Our Custom Provider */} | |
<Comp1 /> | |
</UserProvider> | |
<button onClick={changeNumberHandler}>Changing Main Component Number</button> | |
</div> | |
); | |
} | |
export default App; | |
// user.js | |
import React, { | |
useState, | |
useEffect, | |
useContext, | |
useCallback, | |
useMemo | |
} from 'react' | |
import axios from 'axios' | |
const UserContext = React.createContext(undefined); | |
const UserProvider = ({ | |
children | |
}) => { | |
const [user, setUser] = useState(null); | |
const [random, setRandom] = useState(1); | |
useEffect(() => { | |
const url = `https://jsonplaceholder.typicode.com/users/${random}`; | |
axios.get(url).then(res => { | |
setUser(res.data); | |
}).catch(err => { | |
console.error(err) | |
}); | |
}, [random]); | |
const changeUser = useCallback(() => { | |
const randomNumber = Math.floor(Math.random() * 10 + 1); | |
setRandom(randomNumber); | |
}, []) | |
const data = useMemo(() => ([ | |
user, | |
changeUser | |
]), [user, changeUser]) | |
return ( | |
<UserContext.Provider value={data}> | |
{children} | |
</UserContext.Provider> | |
) | |
} | |
const useUser = () => { | |
const context = useContext(UserContext); | |
if (context === undefined) { | |
throw new Error('useUser can only be used inside UserProvider'); | |
} | |
return context; | |
} | |
export { | |
UserProvider, | |
useUser | |
} | |
// comp1.js | |
import React from 'react'; | |
import Comp2 from './comp2'; | |
const Comp1 = () => ( | |
<div className="comp1"> | |
Comp1 | |
<Comp2 /> | |
</div> | |
) | |
export default React.memo(Comp1); | |
// comp2.js | |
import React from 'react'; | |
import Comp3 from './comp3'; | |
import Comp4 from './comp4'; | |
const Comp2 = () => ( | |
<div className="comp2"> | |
Comp2 | |
<div className="compContainer"> | |
<Comp3 /> | |
<Comp4 /> | |
</div> | |
</div> | |
) | |
export default Comp2; | |
// comp3 | |
import React from 'react'; | |
import { useUser } from './user'; | |
const Comp3 = () => { | |
const [user] = useUser(); | |
return ( | |
<div className="comp3"> | |
Comp3 | |
<hr /> | |
<p>{user && user.id}</p> | |
<p>{user && user.name}</p> | |
<p>{user && user.website}</p> | |
</div> | |
) | |
} | |
export default Comp3; | |
// comp4.js | |
import React from 'react'; | |
import { useUser } from './user'; | |
const Comp4 = () => { | |
const [user, changeUser] = useUser(); | |
return ( | |
<div className="comp3"> | |
Comp4 | |
<hr /> | |
<p>{user && user.id}</p> | |
<p>{user && user.name}</p> | |
<p>{user && user.website}</p> | |
<button onClick={changeUser}>Change User</button> | |
</div> | |
) | |
} | |
export default Comp4; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment