import React, { createContext, useContext } from 'react';
const ThemeContext = createContext('green'); // 초기값이 들어간다.
const useThemeContext = () => {
const theme = useContext(ThemeContext)
return theme
}
function App() {
return (
<ThemeContext.Provider value="blue">
<Toolbar />
</ThemeContext.Provider>
);
}
function Toolbar() {
// The Toolbar component must take an extra "theme" prop
// and pass it to the ThemedButton. This can become painful
// if every single button in the app needs to know the theme
// because it would have to be passed through all components.
return (
<div>
<ThemedButton />
</div>
);
}
const ThemedButton = () => {
const theme = useThemeContext()
return (
<button className={`button-${theme}`}>
button
</button>
)
}
export default App;
➡️ 결론 : Redux를 사용하면 최적화되 상태관리를 할 수 있다.
간단한 counter 예시를 통해서 살펴보자.
우선 counter 스토어이다.
/src/store/counterStore.js
import { observable } from 'mobx';
const counter = observable({
number : 0,
increase() {
this.number++;
},
decrease (){
this.number--;
},
});
export {counter};
➡️ observable 로 객체를 감싸주고 내부에 value 와 action을 다 같이 넣는다.
이렇게 해주면 action에 의한 값 변경을 감지할 수 있다.
/src/useStore.js
import counter from './store/counterStore';
const useStore = () => {
return { counter };
};
export default useStore;
➡️ useStore를 만들어서 여러 개의 스토어들을 한 번에 관리한다.
/src/CounterCompo.js
import React from 'react';
import { observer } from 'mobx-react';
import useStore from "./useStore";
const CounterCompo = observer(() => {
const {counter} = useStore();
return (
<div>
<h1>{counter.number}</h1>
<button onClick={()=> counter.increase()}>+1</button>
<button onClick={()=> counter.decrease()}>-1</button>
</div>
);
});
export default CounterCompo;
➡️ 실제 화면에 렌더링되는 컴포넌트로 버튼을 클릭하면 number의 값을 변경시킨다.
➡️ 값의 변경을 감지하기 위해 컴포넌트도 또한 observer로 감싸줘야 한다.
네이버 오픈 API 를 이용한 실습을 진행.
네이버 뉴스 검색 api 를 이용해 검색 기능 구현.
우선 뉴스 데이터를 관리할 스토어를 생성해준다.
/src/store/newsStore.js
import { observable, configure } from 'mobx';
import axios from "axios";
const URL = "/v1/search/news.json";
const Id = "GFmXV5peCO2IuIYLzayH";
const Secret = "Your Secret Id"; // 제공 받은 Secret id를 넣어주면 된다.
configure({ enforceActions: true });
const News = observable({
searchInput : "",
data : [],
async apiRequest(){
try{
const response = await axios.get(URL, {
headers:{
'X-Naver-Client-Id':Id,
'X-Naver-Client-Secret':Secret,
},
params:{
query : this.searchInput,
}
});
this.data = response.data.items;
}catch(e){
console.log(e);
}
},
})
export default News;
➡️ News 객체를 observable로 감싸준다.
searchInput
은 검색 값이다. api 요청에서 query의 인자로 들어가게 된다.
apiRequest
는 공공 api 에 값을 요청하는 함수이다.
가져온 뉴스 제목 데이터를 실제로 렌더링 해주는 함수형 뉴스 컴포넌트이다.
/src/NewsCompo.js
import React from "react";
import { observer } from "mobx-react";
import useStore from "./useStore";
const NewsCompo = observer(()=>{
const {News} = useStore();
const handleChange =(e)=>{
News.searchInput = e.target.value;
}
const InfoReq = () =>{
News.apiRequest();
}
return <div>
<input value={News.searchInput} onChange={handleChange}></input>
<button onClick = {InfoReq}>검색</button>
{News.data.map((data, idx)=>{
return (<div key={idx}>{data.title}<br></br></div>)
})}
</div>
});
export default NewsCompo;
➡️ 컴포넌트를 observer로 감싸준다.
[결과]
잘나오는 것을 확인할 수 있다.