전역상태관리 미사용
props를 통해 가지고있는 state를 다른 컴포넌트에 내려준다
(다른 컴포넌트에게 전달하기 위해 여러차례 props를 전달해야함 (props drilling))
전역상태관리 사용
전역상태를 하나 두고(ex.store) 그곳에 업데이트 하면 다른 컴포넌트들이 state를 내려다 사용한다
(store는 여러개가 될 수도 있음)
단점: 컴포넌트 재사용, 유닛테스트 작성이 어려움
컴포넌트 안에서 다른 컴포넌트를 가져다 쓰는 패턴
props drilling을 해결하기 위해 컴포넌트 합성을 사용하는것이 좋을 수 있다
컴포넌트 합성을 통해 해결한 경우
Inversion of control이 발생한다
let name = '';
const Hello1 = () => (
<div>
this is Hello1. and Name is {name}
<Hello2 />
</div>
);
const Hello2 = () => (
<div>
this is Hello2. and Name is {name}
<Hello3 />
</div>
);
const Hello3 = () => (
<div>
this is Hello3. and Name is {name}
<Hello4 />
</div>
);
const Hello4 = () => (
<div>
this is Hello4.
<div>Hello {name}!</div>
</div>
);
const App = () => {
const handleClickButton = () => {
name = 'asdf';
}
return (
<>
<Hello />
<button onClick = {handleClickButton}>click me!</button>
</>
);
}
const App = () => {
const [uselessState, setUselessState] = React.useState(false);
const handleClickButton = () => {
name = 'asdf';
setUselessState(true);
}
import { createContext, useContext } from "react";
const defaultName = 'asdf';
const NameContext = createContext(defaultName);
const Hello1 = () => {
const name = useContext(NameContext);
return (
<div>
this is Hello1. and Name is {name}
<Hello4 />
</div>
);
};
const Hello4 = () => {
const name = useContext(NameContext);
return (
<div>
this is Hello4
<div>Hello {name}!</div>
</div>
);
};
const App = () => (
<NameContext.Provider value={defaultName} >
<Hello1 />
</NameContext.Provider>
);
export default App;
import { createContext, useContext } from "react";
const defaultName = 'asdf';
const NameContext = createContext(defaultName);
const Hello1 = () => {
const name = useContext(NameContext);
return (
<div>
this is Hello1. and Name is {name}
<Hello4 />
</div>
);
};
const Hello4 = () => {
const name = useContext(NameContext);
return (
<div>
this is Hello4
<div>Hello {name}!</div>
</div>
);
};
const App = () => (
<NameContext.Provider value={defaultName} >
<Hello1 />
</NameContext.Provider>
);
export default App;
import React, { useState, createContext, useContext } from "react";
const NameContext = createContext('');
const Hello1 = () => {
const name = useContext(NameContext);
const hello4 = React.useMemo(() => {
console.log('re-render in hello1');
return <Hello4 />
}, []);
return (
<div>
this is Hello1. and Name is {name} {hello4}
</div>
);
};
const Hello4 = () => {
console.log('re-render in hello4');
const name = useContext(NameContext);
return (
<div>
this is Hello4. and Name is {name}
</div>
);
};
const App = () => {
const [test, setTest] = useState('asdf');
return (
<>
<input type="text" onChange={(e)=>setTest(e.target.value)} value={test} />
<NameContext.Provider value={test} >
<Hello1 />
</NameContext.Provider>
</>
)
};
export default App
+문제점이 있다면 해결해서 구현해보기
import { createContext, useContext } from "react";
const defaultUser = {
name: 'jin',
id: 'woorung',
};
const UserContext = createContext(defaultUser);
const HelloName = () => {
const { name } = useContext(UserContext);
return (
<div>
this is HelloName. and Name is {name}
</div>
);
};
const HelloId = () => {
const { id } = useContext(UserContext);
return (
<div>
this is HelloId. and Id is {id}
</div>
);
};
// App.tsx
const App = () => (
<UserContext.Provider value={defaultUser} >
<HelloId />
<HelloName />
</UserContext.Provider>
);
export default App;
const HelloName = () => {
const name = useContext(UserContext2);
return (
<div>
this is HelloName. and Name is {name}
</div>
);
};
const HelloId = () => {
const id = useContext(Context1);
return (
<div>
this is HelloId. and Id is {id}
</div>
);
};
// App.tsx
const App = () => (
<Context1.Provider value={defaultId}>
<Context2.Provider value={defaultName}>
<HelloId />
<HelloName />
<Context2.Provider>
<Context1.Provider>
);
export default App;