1. 리덕스툴킷
쉽게 말하면 리덕스를 개량한 것.
코드를 더 적게, 그리고 리덕스를 더 편하게 쓰기 위한 기능들을 흡수해서 만든 것.
2. 툴킷 설치하기
yarn add react-redux @reduxjs/toolkit
=> 일반 리덕스는 Action Value, Action Creator를 별도로 생성해줘야 했다면 리덕스툴킷은 Action Value, Action Creator, Reducer가 하나로 합쳐졌다.
createSlice 사용!!
//createSlice API 뼈대
const counterSlice = createSlice({
name: '', // 이 모듈의 이름
initialState : {}, // 이 모듈의 초기상태 값
reducers : {}, // 이 모듈의 Reducer 로직
})
1. json-server 정의
아주 간단한 DB와 API서버를 생성해주는 패키지 (임시로 사용할 mock data 생성)
2. json-server 설치하기
yarn add json-server
3. json-server 실행하기
yarn json-server --watch db.json --port 4000
1. Axios
node.js와 브라우저를 위한 Promise 기반 http 클라이언트
=> http를 이용해서 서버와 통신하기 위해 사용하는 패키지
yarn add axios
2. GET
axios.get => 서버의 데이터를 조회할 때 사용
// src/App.js
import React, { useEffect, useState } from "react";
import axios from "axios"; // axios import 합니다.
const App = () => {
const [todos, setTodos] = useState(null);
// axios를 통해서 get 요청을 하는 함수를 생성
// 비동기처리를 해야하므로 async/await 구문을 통해서 처리
const fetchTodos = async () => {
const { data } = await axios.get("http://localhost:4000/todos");
setTodos(data); // 서버로부터 fetching한 데이터를 useState의 state로 set
};
// 생성한 함수를 컴포넌트가 mount 됐을 때 실행하기 위해 useEffect를 사용
useEffect(() => {
// effect 구문에 생성한 함수를 넣어 실행
fetchTodos();
}, []);
// data fetching이 정상적으로 되었는지 콘솔을 통해 확인합니다.
console.log(todos);
return <div>App</div>;
};
export default App;
3. POST
axios.post => 서버에 데이터를 추가할 때 사용
// src/App.jsx
import React, { useEffect, useState } from "react";
import axios from "axios"; // axios import 합니다.
const App = () => {
// 새롭게 생성하는 todo를 관리하는 state
const [todo, setTodo] = useState({
title: "",
});
const [todos, setTodos] = useState(null);
const fetchTodos = async () => {
const { data } = await axios.get("http://localhost:3001/todos");
setTodos(data);
};
const onSubmitHandler = async(todo) => {
//1. 이때 todos는 [{투두하나}]임
await axios.post("http://localhost:3001/todos", todo); // 이때 서버에 있는 todos도 [{투두하나}]임
// 근데 여기서 서버 요청이 끝나고 서버는 [{투두가},{두개임}]
setTodos([...todos, todo]) 2. <-- 만약 이게 없다면, go to useEffect
//4. 새로고침해서 진짜 현재 서버 데이터를 받아오기전에 상태를 똑같이 동기시켜줌
//5. 어떻게보면 유저한테 서버에서 새로 받아온것처럼 속이는것
};
useEffect(() => {
fetchTodos(); //3. 새로고침해서 여기를 다시 실행해줘야 서버값이 새로 들어옴 e.g) [{투두가},{두개임}]
}, []);
return (
<>
<form
onSubmit={(e) => {
e.preventDefault();
onSubmitHandler(todo);
}}
>
<input
type="text"
onChange={(ev) => {
const { value } = ev.target;
setTodo({
...todo,
title: value,
});
}}
/>
<button>추가하기</button>
</form>
<div>
{todos?.map((todo) => (
<div key={todo.id}>{todo.title}</div>
))}
</div>
</>
);
};
export default App;
4. DELETE
axios.delete => 저장되어 있는 데이터를 삭제하고자 요청을 보낼 때
const onClickDeleteButtonHandler = (todoId) => {
axios.delete(`http://localhost:3001/todos/${todoId}`);
};
//버튼부분
<button
type="button"
onClick={() => onClickDeleteButtonHandler(todo.id)}
>
삭제하기
</button>
5. PATCH
axios.patch => 어떤 데이터를 수정하고자 서버에 요청을 보낼 때
1. instance 만들기, baseURL 설정하기
src > axios > api.js
import axios from "axios";
// axios.create의 입력값으로 들어가는 객체는 configuration 객체
const instance = axios.create({
baseURL: "http://localhost:4000",
});
export default instance;
App.jsx
import "./App.css";
import { useEffect } from "react";
import api from "./axios/api";
function App() {
useEffect(() => {
api
.get("/cafe")
.then((res) => {
console.log("결과 => ", res.data);
})
.catch((err) => {
console.log("오류가 발생하였습니다!");
});
}, []);
return <div>axios 예제입니다.</div>;
}
export default App;
2. request, response에 적용해보기
요청을 보낼 때, 그리고 서버로부터 응답을 받을 때(실패할 때) 특정한 일을 수행해야 한다면?
src > axios > api.js
import axios from "axios";
const instance = axios.create({
baseURL: "http://localhost:4000",
});
instance.interceptors.request.use(
function (config) {
// 요청을 보내기 전 수행
console.log("인터셉트 요청 성공!");
return config;
},
function (error) {
// 오류 요청을 보내기 전 수행
console.log("인터셉트 요청 오류!");
return Promise.reject(error);
}
);
instance.interceptors.response.use(
function (response) {
console.log("인터넵트 응답 받았어요!");
// 정상 응답
return response;
},
function (error) {
console.log("인터셉트 응답을 받지 못했어요");
return Promise.reject(error);
}
);
export default instance;
=>요청과 응답 중간에 가로채서 어떠한 작업을 수행!!
1. Redux 미들웨어
리덕스에서 dispatch를 하면 action이 리듀서로 전달되고, 리듀서는 새로운 state를 반환한다. 미들웨어를 사용하면 이 과정에서 우리가 하고싶은 작업들을 넣어서 할 수 있다.
2. thunk
createAsyncThunk를 이용createAsyncThunk()의 첫번째 자리에는 action value, 두번째에는 함수가 들어감