1. 미들웨어를 사용해야 하는 이유
리덕스의 플로우차트 : UI -> Dispatch -> Action -> Store(Reducer)(state) -> UI
리덕스는 동기적으로 처리가 되는데 변경값이 있으면 바로 동작해서 API 같은 데이터를 불러올때 비동기 작업이 힘들다.
API 데이터를 받은 이후에 작업을 해야하기 때문에 미들웨어를 사용해야 한다.
2. 미들웨어란
미들웨어는 양 쪽을 연결해주고 데이터를 주고 받을수 있도록 중간에서 매개 역할을 담당하는 소프트웨어다.
컴퓨터에 있는 프로세스들에게 어떤 서비스를 사용할수 있도록 연결해주는 소프트웨어를 말한다.
리덕스 미들웨어에는 saga, thunk 등이 있다.
그 중 thunk가 적용하기도 쉽고 많이 사용한다.
3. thunk
thunk 참고 사이트
thunk 설치 명령어
npm i redux-thunk
redux 저장소를 만들고 만드는 와중 리듀서 함수를 적용시켜준다.
react-redux 만들어진 저장소를 사용하는데 편하게 쓸수 있게 리액트 훅함수를 지원해준다.
(1) redux, react-redux 설치
(2) store.js 만들고 createStore로 저장소 만들기
(3) reducer.js 만들고 store.js에 매개변수로 reducer 전달
(4) 완성된 저장소를 index.js에 가져와서 App컴포넌트에 적용
thunk가 해주는 일은 Action Creators라는 함수를 만들어주는 것이다.
Action Creators 함수는 함수를 반환한다.
thunk는 dispatch를 딜레이 시켜주는 역할이다.
4. 날씨 API 받아오기
API 받은곳
/redux/store.js
import reducer from "./reducer";
import { createStore, applyMiddleware } from "redux";
import thunk from "redux-thunk";
const store = createStore(reducer, applyMiddleware(thunk));
export default store;
applyMiddleware : 미들웨어를 적용 시켜주는 함수
applyMiddleware() 매개변수로 적용시킬 미들웨어 매개변수로 전달
createStore 함수의 두번째 배개변수로 applyMiddleware 함수를 전달하고
applyMiddleware 함수의 매개변수로 사용할 미들웨어(thunk)를 전달한다.
/middleware/weatherAction.js
import axios from "axios";
const getWeather = (name) => {
return async (dispatch, getState) => {
const data = await axios({
url: `https://api.openweathermap.org/data/2.5/weather?q=${name}&appid=자기API주소`,
});
dispatch({ type: "GET_WEATHER_DATA", payload: data });
};
};
export const weather = { getWeather };
getState() 함수는 store 저장소에 있는 state 객체를 반환해준다.
미들웨어에서 arrowfunction을 return 해준다.
/redux/reducer/weather.js
let init = {
weatherData: {},
};
const weather = (state = init, action) => {
const { type, payload } = action;
switch (type) {
case "GET_WEATHER_DATA":
return { ...state, weatherData: payload };
default:
return state;
}
};
export default weather;
App.js
import "./App.css";
import { useDispatch, useSelector } from "react-redux";
import { weather } from "./middleware";
import { useState } from "react";
function App() {
const dispatch = useDispatch();
const getWeather = (name) => {
dispatch(weather.getWeather(name));
};
const weatherData = useSelector((state) => state.weather.weatherData);
const [name, setName] = useState("");
return (
<div className="App">
<label>도시 이름</label>
<input onChange={(e) => setName(e.target.value)} />
<button
onClick={() => {
getWeather(name);
}}
>
날씨 검색
</button>
<div>
지금 {weatherData && weatherData.data?.name}의 날씨는 :
{weatherData && weatherData.data?.weather[0]?.main}
</div>
</div>
);
}
export default App;
App.js에서 dispatch로 action을 보내주는것을 시작점, 미들웨어에서 dispatch로 action을 보내주고 reducer에서 값을 받았을때가 끝나는 시점이라고 생각하면 된다.
나중에 로딩창을 적용할때도 이와 비슷하게 적용하면 된다.
'개발 > React' 카테고리의 다른 글
[React] i18next (0) | 2023.04.07 |
---|---|
[React] express 서버와 연결하기 (0) | 2022.10.07 |
[React] 게시판만들기(Redux) (0) | 2022.10.04 |
[React] Redux (1) | 2022.10.04 |
[React] 게시판 만들기 (0) | 2022.09.26 |