( ⚠️ 이전 포스팅에서 이어지는 내용입니다 )
이전 포스팅에서 하게 될 내용은 이전 포스팅에서 했던 context의 생성, 수정을 통해 자식 노드에 변경 사항을 적용하는 기능에 대해 알아보았습니다.
그런데 만약 엄청나게 많은 데이터가 context에 들어가게 되면 어떡할까? 물론 복잡해 질것이고 이는 곧 개발자의 혼란으로 이어지게 되고... 이는 곧 낮은 퀄리티의 결과로 이어지게 됩니다...
그래서 이번 포스팅에서는 다중 context를 생성하고 이를 하위 노드에서 접근하고, 수정하는 기능을 추가해 볼 예정입니다.
한줄 요약 👉 게시판 만들거임 ㅎ
👇 먼저 AuthContext 를 새롭게 만들어 줍니다.
// AuthContext.js
export const AuthContext = createContext(); // ThemeContext 외의 다른 context 생성.
function AuthContextProvider (props) {
const [state,setState] = useState({
isAuthenticated: false
})
// 기본값 설정
const toggleAuth = () =>{
setState({isAuthenticated : !state.isAuthenticated})
}
// 수정 함수 작성
return(
<AuthContext.Provider value={{...state,toggleAuth: toggleAuth}}> // 값 넘겨줌
{props.children} // 모든 자식에게 이용권한 줌.
</AuthContext.Provider>
)
}
export default AuthContextProvider
👇 아래와 같이 App에서 새로 생성한 context도 적용시켜줌.
//App.js
function App() {
return (
<div className="App">
<ThemeContextProvider>
<AuthContextProvider>
<Navbar />
<ThemeToggle/>
</AuthContextProvider>
</ThemeContextProvider>
</div>
);
}
👇 하위 노드에서 접근하는 것은 이전 포스팅과 마찬가지로 2 가지가 있습니다. useContext 사용 or Consumer 사용..아래 코드는 Consumer을 사용한 접근입니다.
// Navbar.js
...
function Navbar () {
return (
//요로코롬 마치 2중 for문을 연상 시키듯이 해줌..
<AuthContext.Consumer>{(authContext) => (
<ThemeContext.Consumer>{(context) =>{
const { isAuthenticated , toggleAuth} = authContext
const { isLightTheme, light, dark } = context;
const theme = isLightTheme ? light : dark;
return(
<nav style={{background: theme.ui, color: theme.syntax }}>
<h1>Context App</h1>
<div onClick ={toggleAuth}>
{isAuthenticated ? 'Logged in' : 'Logged out '}
</div>
<ul>
<li>Home</li>
<li>About</li>
<li>Contact</li>
</ul>
</nav>
)
}}
</ThemeContext.Consumer>
)}
</AuthContext.Consumer>
);
}
export default Navbar;
👇 게시판 역할을 할 BookContext를 새롭게 만들어 줍니다
//BookContex.Js
import uuid from 'uuid/v1'
export const BookContext = createContext();
function BookContextProvider(props) {
const [books, setBooks] = useState([
{title: 'name of the wind', author:'patrick rothfuss',id: 1},
{title: 'the way of kings', author:'brandon sanderson', id: 2},
])
const addBook = (title,author) =>{
setBooks([...books,{title,author, id: uuid() }])
}
// book 정보를 추가 시켜줌 ( add )
const removeBook = (id) =>{
setBooks(books.filter(book => book.id !== id))
}
// book 정보를 삭제해줌 ( del )
return(
<BookContext.Provider value ={{books, addBook, removeBook}}>
{props.children}
</BookContext.Provider>
)
}
export default BookContextProvider
👇 BookContext에 있는 값을 표현해줌
// BookList
function BookList () {
const {isLightTheme , light, dark} = useContext(ThemeContext)
const { books } = useContext(BookContext)
const theme = isLightTheme ? light : dark;
return books.length ? (
<div className="book-list" style={{color : theme.syntax, background : theme.bg}}>
<ul>
{books.map(book =>{
return(
<BookDetails book={book} key = {book.id}/>
)
})}
</ul>
</div>
) : (
<div className ="empty">
No books to read. Hello free time :)
</div>
);
}
👇 BookContext 값 표현
// BookDetails
function BookDetails ({book}) {
const {removeBook} = useContext(BookContext)
return(
<li onClick ={() => removeBook(book.id)}>
<div className ="title"><h4> - {book.title}</h4></div>
<div className ="author">{book.author}</div>
</li>)
}
export default BookDetails
👇 Book 추가 해주는 컴포넌트 작성
// NewBookForm
function NewBookForm() {
const {addBook} = useContext(BookContext);
const [title,setTitle] = useState('');
const [author,setAuthor] = useState('');
const handleSubmit = (e) =>{
e.preventDefault()
addBook(title,author); // 컨텍스트에 book 추가해줌
setTitle(''); // 초기화
setAuthor(''); // 초기화
}
return(
<form onSubmit={handleSubmit}>
<input type="text" placeholder="book title" value={title} onChange={(e) => setTitle(e.target.value)} required/>
<input type="text" placeholder="book author" value={author} onChange={(e) => setAuthor(e.target.value)} required/>
<input type="submit" value="add book" />
</form>
);
}
👇 모두 한곳에 모아줌
function App() {
return (
<div className="App">
<ThemeContextProvider>
<AuthContextProvider>
<Navbar />
<BookContextProvider>
<BookList />
<NewBookForm/>
</BookContextProvider>
<ThemeToggle/>
</AuthContextProvider>
</ThemeContextProvider>
</div>
);
}
👇 원래 모습
👇 항목을 선택하게 되면,
👇 새로운 책 추가