React.js Axios Package,Side Effect,HTTP Request,Interceptors
01 Feb 2021 | ReactReact.js Axios Package,Side Effect,HTTP Request,Interceptors
-
Axios Package
- axios 패키지는 브라우저, Node.js를 위한 Promise API를 활용하는 HTTP 비동기 통신 라이브러리이다
- 백엔드와 프론트엔드간 통신을 위해 사용되는 Ajax의 라이브러리중 하나이다
- npm install –save axios 설치
- GET, PUT, POST, DELETE 등 메소드로 API 요청을 할 수 있다
- 공통된 URL을 baseURL로 지정하여 각 컴포넌트에서 URL을 귀찮게 일일이 다 안적어도 된다
- 공통 헤더 지정도 가능
axios.defaults.baseURL = 'http://어쩌구..' axios.defaults.headers.common['Authorization'] = 'AUTH_TOKEN'; axios.defaults.headers.post['Content-Type'] = 'application/json';
- 사용자 정의 인스턴스
const instance = axios.create({ baseURL: 'http;//어쩌구..' }); instance.defaults.headers.common['Authorization'] = 'AUTH TOKEN';
-
JSON Placeholder
- 서버가 없을 때, API 테스트를 할 수 있는 사이트로 dummy 데이터를 제공한다
-
Side Effect
- 서버로부터 데이터를 가져온다던지, 수동으로 리액트 컴포넌트의 DOM을 수정한다던지 이를 리액트에서는 side effect라 한다
- 컴포넌트가 렌더링된 이후에 비동기로 처리되어야 하는 부수적인 효과들이다
- side effect는 Clean-up가 필요한 것과 그렇지 않은 것 두 가지로 구분된다
- 리액트가 DOM을 렌더링한 뒤 추가로 코드를 실행하는 경우 : 네트워크 리퀘스트, DOM 수동 조작, 로깅 등은 Clean-up이 필요 없는 side-effect이다
- Clean-up이 필요한 side-effect는 외부 데이터에 subscription을 설정해야하는 경우 등이 있다
-
HTTP Request (GET)
- 클래스 방식의 ComponentDidMount() lifecycle 메소드는 최초 렌더링 후 필요한 HTTP Request를 보내는 side effect를 설치하기 위한 최적의 장소이다
- axios.get 메소드로 리소스 조회 요청을 보낼 수 있는데 일반적으로 데이터를 받기까지 시간이 걸리고 리액트는 다음 line의 코드를 바로 실행해버린다
- 데이터를 다 못받았는데 다음 코드가 실행되면 예상치 못한 결과가 나오므로 primose를 사용하고 then 안에 다음 코드를 작성하도록 하자
import axios from 'axios'; componentDidMount() { // JSON placeholder의 dummy data axios.get('http://jsonplaceholder.typicode.com/posts') .then((response) => {console.log(response)}); } // 데이터 조회에 성공하면 HTTP 상태코드 200을 볼 수 있다
- ComponentDidUpdate() lifecycle 메소드는 사용자의 입력에 따라 re-render가 되며, 그에 필요한 HTTP Request side effect를 설치하기에 좋은 곳이다
- 이 때, promise 안의 setState로 re-render가 일어나 다시 HTTP Request를 하게되는 무한 루프에 빠지지 않도록 조심하자
class Post extends Component { state = { loadedData: null; }; // 사용자의 원하는 데이터를 요청하여 출력 componentDidUpdate() { if(this.props.id) { if(!this.state.loadedData || // 최초 한 번 실행을 위하여 this.state.loadedData && this.state.loadedData.id !== this.props.id) { // 무한루프를 끊기 위해 axios.get('URL...') .then(response => { this.setState({loadedData: response.data}) }); }; } } }
-
HTTP Request (POST)
import axios from 'axios'; postDataHandler = () => { const post = { title: this.state.title, body: this.state.content, author: this.state.author, } axios.post('URL...', post) // 두 번째 인자로 데이터 전달 .then(response => { alert('전송 성공'); }); }
-
HTTP Request (DELETE)
deleteDataHandler = () => { axios.delete('URL...') // 두 번째 인자로 데이터 .then(response => { alert('삭제 성공'); }); }
-
Handling HTTP Request Fail
- 요청한 request가 항상 작동하리란 법은 없다
- 그래서 그 때를 대비하여 무언가 처리를 하는 것이 좋다
- axios의 promise chaining에 .catch를 추가하여 error가 발생했을 시 무언가 실행되도록 할 수 있다
axios.get('URL...').then(response => { // 정상적인 실행문 }).catch(error => { // error 발생시 실행문 })
-
Interceptors
- then, catch로 요청이 처리되기 전에 axios의 interceptors로 응답을 가로챌 수 있다
- 이를 활용하여 모든 요청에 대한 알림 팝업을 띄운다던지, 에러 발생시 공통된 메시지를 띄운다던지 등등 할 수 있다
- 주로 axios가 사용되는 상위 컴포넌트에 많이 들어간다
// 요청 인터셉터 추가 axios.interceptors.request.use(config => { // 요청을 보내기 전에 수행할 일 // ... return config; // return 필수 }, error => { // 오류 요청을 보내기전 수행할 일 // ... return Promise.reject(error); }); // 응답 인터셉터 추가 axios.interceptors.response.use(response => { // 응답 데이터를 가공 // ... return response; }, error => { // 오류 응답을 처리 // ... return Promise.reject(error); });
- interceptor 제거는 use 대신 eject를 사용하면 된다