function App() {
return <Toolbar theme="dark" />;
}
// theme 변수를 사용하지 않음에도 불구하고 prop 전달을 위해 theme 변수를 알아야 함
function Toolbar(props) {
return (
<div>
<ThemedButton theme={props.theme} />
</div>
);
}
function ThemedButton(props) {
return <Button theme={props.theme} />;
}
import { createContext, useContext } from 'react';
const ThemeContext = createContext('light');
function App() {
return (
<ThemeContext.Provider value="dark">
<Toolbar />
</ThemeContext.Provider>
);
}
function Toolbar({}) {
return (
<div>
<ThemedButton />
</div>
);
}
function ThemedButton() {
const color = useContext(ThemeContext);
render() {
return <Button theme={color} />;
}
}
// 기존 코드로 Page부터 avatar까지 prop이 넘겨지는 상황
<Page user={user} avatarSize={avatarSize} />
<PageLayout user={user} avatarSize={avatarSize} />
<NavigationBar user={user} avatarSize={avatarSize} />
<Link href={user.permalink}>
<Avatar user={user} size={avatarSize} />
</Link>
// Link부터를 최상단 Page코드로 분리 가능
function Page(props) {
const user = props.user;
const userLink = (
<Link href={user.permalink}>
<Avatar user={user} size={props.avatarSize} />
</Link>
);
return <PageLayout userLink={userLink} />;
}
// 이제 다른 컴포넌트들은 user, avatarSize에 대한 prop을 몰라도 됨
<Page user={user} avatarSize={avatarSize} />
<PageLayout userLink={...} />
<NavigationBar userLink={...} />
{props.userLink}
// prop에 컴포넌트를 전달하는 방식을 통한 추가 리팩토링
function Page(props) {
const user = props.user;
const content = <Feed user={user} />;
const topBar = (
<NavigationBar>
<Link href={user.permalink}>
<Avatar user={user} size={props.avatarSize} />
</Link>
</NavigationBar>
);
return (
<PageLayout
topBar={topBar}
content={content}
/>
);
}
const MyContext = React.createContext(defaultValue);
<MyContext.Provider value={/* any value */}>
// Provider의 부모가 렌더링 될때마다 레퍼런스가 변경되기 때문에 자식 요소가 불필요하게 업데이트 됨
function App() {
return (
<MyContext.Provider value={{something: 'something'}}>
<Toolbar />
</MyContext.Provider>
);
}
// state를 사용해 업데이트 방지
function App() {
const [something, setSomething] = useState("something");
return (
<MyContext.Provider value={something}>
<Toolbar />
</MyContext.Provider>
);
}
const value = useContext(MyContext);
//example
function Button() {
const theme = useContext(ThemeContext);
return <button className={theme} />;
}
<MyContext.Consumer>
{value => /* rendering */}
</MyContext.Consumer>
//example
function Button() {
return (
<ThemeContext.Consumer>
{theme => (
<button className={theme} />
)}
</ThemeContext.Consumer>
);
}
출처:
https://ko.reactjs.org/docs/context.html
https://ko.reactjs.org/docs/hooks-reference.html#usecontext
https://beta.reactjs.org/reference/react/createContext#consumer