DBILITY

react axios example 본문

front-end & ui/react

react axios example

DBILITY 2022. 2. 16. 11:35
반응형

일주일에 한번씩만 보자. 사용안하니 공부한게 사라진다.

먼저 axios를 npm으로 설치하고

PS C:\Dev64\workspace\project> npm install axios@0.26.0
PS C:\Dev64\workspace\project> npm ls
project@0.1.0 C:\Dev64\workspace\project
+-- @testing-library/jest-dom@5.16.2
+-- @testing-library/react@12.1.2
+-- @testing-library/user-event@13.5.0
+-- axios@0.26.0
+-- bootstrap@4.6.0
+-- react-bootstrap@1.6.4
+-- react-dom@17.0.2
+-- react-icons@4.3.1
+-- react-redux@7.2.6
+-- react-router-dom@6.2.1
+-- react-scripts@5.0.0
+-- react@17.0.2
+-- redux@4.1.2
`-- web-vitals@2.1.4

redux reducer에 axios로 fetch한 데이터의 후처리 action도 추가해 줘야

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import {Provider} from "react-redux";
import {combineReducers, createStore} from "redux";
import data from "./data";

const roomState = {rooms: data, backup: data}

const roomReducer = (state = roomState, action = {}) => {
    if (action.type === 'inform') {
        const id = parseInt(action.payload.id);
        const copyRooms = [...state.rooms];
        const idx = copyRooms.findIndex((v) => v.id === id);
        copyRooms[idx].inform_count++;
        return Object.assign({}, state, {rooms: copyRooms});
    } else if (action.type==='requestData') {
        return Object.assign({}, state, {rooms: action.payload.data});
    } else {
        return state;
    }
};

const store = createStore(combineReducers({rooms: roomReducer}));

ReactDOM.render(
    <React.StrictMode>
        <Provider store={store}>
            <App/>
        </Provider>
    </React.StrictMode>,
    document.getElementById('root')
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

실제 axios fetch하는 component쪽의 코드도 추가한다.

import {useDispatch, useSelector} from "react-redux";
import {Button, Col, Row} from "react-bootstrap";
import {FaRegBellSlash} from "react-icons/fa";
import {dataUrl} from "../data";
import axios from "axios";


const Rooms = () => {
    const dispatch = useDispatch();
    const {rooms} = useSelector(state => state.rooms);
    const handlerGetData = (e) => {
        let copyRooms = [...rooms];
        console.log(copyRooms);
        axios.get(dataUrl).then(response => {
            console.log(response);
            if (response.data.length > 0) {
                const result = response.data;
                let maxId = copyRooms.reduce((previousValue, currentValue) => Math.max(previousValue, (currentValue.id)), 0);
                const rsData = result.map((v) => {
                    v.id = ++maxId;
                    return v;
                });
                console.log(rsData);
                copyRooms = [...rooms, ...rsData];
            } else {
                //data not found
            }
        }).catch(reason => {
            console.log(reason);
        }).finally(() => {
            console.log('axios get method finally');
            dispatch({type: 'requestData', payload: {data: copyRooms}});
        });
    };
    const getData = (e) => {
        handlerGetData(e)
    }
    return (
        <>
            <Row>
                {
                    rooms.map((v, i) => {
                        return (
                            <Col md={4} className={'room-box'} key={i}>
                                <h4>{v.title}</h4>
                                <img src={`${v.image}`} alt={v.title}/>
                                <p>{new Intl.NumberFormat('ko-KR', {style: 'currency', currency: 'KRW'}).format(v.price)}원</p>
                                <p>신고건수 : {v.inform_count}{`  `}<Button variant={'danger btn-sm'} data-id={v.id} onClick={(e) => dispatch({
                                    type: 'inform',
                                    payload: {id: e.target.dataset.id}
                                })}><FaRegBellSlash className={'mb-1'}/> 허위매물</Button></p>
                            </Col>
                        )
                    })
                }
            </Row>
            <Button variant={'outline-secondary btn-sm mt-2'} onClick={getData}>more</Button>
        </>
    )

}

export default Rooms;

const result = response.data; 는 서버응답에 따른 데이터이고,

let maxId = copyRooms.reduce((previousValue, currentValue) => Math.max(previousValue, (currentValue.id)), 0);

maxId는 실제 data object내의 key로 id가 존재하나 3개로 고정된 테스트용 데이터라 받아온 후 변경을 시키기 위해 필요한 것이다.

다음과 같이 map을 이용해 변경해 준다.

const rsData = result.map((v) => {
      v.id = ++maxId;
      return v;
});

아래 그림1 의 more를 눌렀을때 동작하는 코드다.

그림 1

반응형

'front-end & ui > react' 카테고리의 다른 글

react state-management zustand  (0) 2022.03.15
react spring boot multipart upload  (0) 2022.02.22
react eslint message disable  (0) 2022.02.16
react react-icons  (0) 2022.02.15
react react-redux  (0) 2022.02.15
Comments