Skip to content

Instantly share code, notes, and snippets.

@sangkukbae12
Created April 27, 2020 22:51
Show Gist options
  • Save sangkukbae12/c70a85bfe046987e7c3e359c3bc722f3 to your computer and use it in GitHub Desktop.
Save sangkukbae12/c70a85bfe046987e7c3e359c3bc722f3 to your computer and use it in GitHub Desktop.
react context pattern
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