ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • React RestAPI - 2
    Front-End/React 2024. 9. 3. 21:10
    728x90
    반응형

    React RestAPI - 2

     

    앞 장에서는 GET 방식만 다뤘지만 이제 나머지 HTTP 메서드도 다뤄보겠다. 

     

     

     

    1. PUT

    화면

     

    지금 화면 상으로는 문제 없이 동작하는 것 같지만, 새로고침하면 체크박스가 해제된 상태로 렌더링된다.

    당연하지만 지금 db에 값을 바꾼 것이 아니라 state만 바꿔주고 있기 때문이다.

     

    그래서 실제로 체크할 때마다 db에 값이 변동되게 해보자.

     

    Word.js

    function toggleDone() {
        fetch(`http://localhost:3001/words/${word.id}`, {
            method : 'PUT',
            headers : {
                'Content-Type' : 'application.json'
            },
            body : JSON.stringify({
                ...word,
                isDone : !isDone
            })
        })
            .then(res => {
                if (res.ok) {
                    setIsDone(!isDone);
                }
            })
    }

    setIsDone(!isDone); 한 줄만 있었던 toggleDone() 함수를 이렇게 수정했다.

    이제 실제로 데이터가 변경되고, res.ok를 통해 변경이 잘 된 것을 확인하면 state도 수정한다.

    이제 새로고침해도 내가 마지막에 두었던 상태로 렌더링된다.

     

     

     

    2. DELETE

    수정을 했으니 삭제도 해보자.

    function del() {
        if (window.confirm('삭제 하시겠습니까?')){
            fetch(`http://localhost:3001/words/${word.id}`, {
                method : 'DELETE'
            })
        }
    }
    <button className="btn_del" onClick={del}>삭제</button>

    실수로 삭제하기 전에 알림창을 통해 확인 정도만 시켜주고 있다.

     

    그런데 이렇게 하면, 삭제를 수락했을 때 새로고침을 해야지만 삭제된 화면을 볼 수 있다.

    그래서 삭제가 되면 컴포넌트를 다시 렌더링하게 만들어보자.

     

    앞에서 다루었는데, 리액트는 state에 변동사항이 생기면 컴포넌트를 다시 렌더링하니까,

    단어를 state에 등록하고 삭제를 하고나서 단어의 state에 변동을 주자.

     

    export default function Word({ word:w }) {
        const [word, setWord] = useState(w)

    일단 state에 word를 등록했다.

    이런 문법도 가능하길래 그냥 가져와봤다. 이제 word를 변동시키는 것도 작성해보자.

     

    function del() {
        if (window.confirm('삭제 하시겠습니까?')){
            fetch(`http://localhost:3001/words/${word.id}`, {
                method : 'DELETE'
            })
                .then(res => {
                    if (res.ok) {
                        setWord({ id: 0});
                    }
                });
        }
    }
    
    if (word.id === 0){
        return null;
    }
    
    return (
        <>
            <tr className={isDone ? 'off' : ''}>
                <td>
                    <input type="checkbox" checked={isDone} onChange={toggleDone}/>
                </td>
                <td>
                    {word.eng}
                </td>
                <td>
                    {isShow && word.kor}
                </td>
                <td>
                    <button onClick={toggleShow}>뜻보기</button>
                    <button className="btn_del" onClick={del}>삭제</button>
                </td>
            </tr>
        </>
    )

    삭제가 정상적으로 되면 setWord를 통해 state에 변동을 주고,

    아래에서 조건문을 통해 null을 반환하고 있다.

    null을 반환하는 것 자체에 큰 의미가 있는 것은 아니고,

    이렇게 return문을 작성해주면 아래의 JSX가 리턴되지 않는 것이 의의다.

     

     

     

    3. PUT

    조회 수정 삭제를 했으니 마지막은 등록이다.

    등록용 페이지를 먼저 만들어주자.

     

    CreateWord.js

    export default function CreateWord() {
        const days = useFetch("http://localhost:3001/days");
    
        
    
        return (
            <form>
                <div className="input_area">
                    <label>단어</label>
                    <input type="text" placeholder="example"/>
                </div>
                <div className="input_area">
                    <label>뜻</label>
                    <input type="text" placeholder="예시"/>
                </div>
                <div className="input_area">
                    <label>날짜</label>
                    <select>
                        {
                            days.map(day => (
                                <option key={day.id} value={day.day}>
                                    {day.day}
                                </option>
                            ))
                        }
                    </select>
                </div>
                <button>저장</button>
            </form>
        );
    }

     

    App.js의 return문에 추가

    <Route path="/create_word" element={<CreateWord></CreateWord>}>
    
    </Route>

     

    화면

    이렇게 생겼다.

     

    이 상태에서 저장을 누르면 새로고침이 되버리는데 내 마음대로 할 수 있게 코드를 바꿔주겠다.

    먼저 제출을 막기 위해 다음 코드 추가

    function onSubmit(e) {
        e.preventDefault();
    }
    <form onSubmit={onSubmit}>

     

    그리고 각 값에 접근할 수 있게 만들어보자.

    const engRef = useRef(null);
    const korRef = useRef(null);
    const dayRef = useRef(null);
    <input type="text" placeholder="example" ref={engRef}/>
    <input type="text" placeholder="예시" ref={korRef}/>
    <select ref={dayRef}>

    각 입력태그에 ref 속성을 추가해주었다.

    이러면 렌더링 결과가 DOM에 영향을 끼친 후에 해당 값에 접근할 수 있다.

     

    onSubmit()에 fetch() 추가

    function onSubmit(e) {
        e.preventDefault();
    
        fetch(`http://localhost:3001/words`, {
            method : 'POST',
            headers : {
                'Content-Type' : 'application.json'
            },
            body : JSON.stringify({
                day : dayRef.current.value,
                eng : engRef.current.value,
                kor : korRef.current.value,
                isDone : false
            })
        })
            .then(res => {
                if (res.ok) {
                    alert("생성이 완료되었습니다.");
                }
            });
    }

     

    정상적으로 작동한다.

    하지만 전에 배웠던 PRG 흐름으로 작성하면 더 좋을 것 같다.

     

     

     

    4. navigate

    예전엔 history였는데 이게 나중에 바뀌었다.

    const days = useFetch("http://localhost:3001/days");
    const navigate = useNavigate();
    
    function onSubmit(e) {
        e.preventDefault();
    
        fetch(`http://localhost:3001/words`, {
            method : 'POST',
            headers : {
                'Content-Type' : 'application.json'
            },
            body : JSON.stringify({
                day : dayRef.current.value,
                eng : engRef.current.value,
                kor : korRef.current.value,
                isDone : false
            })
        })
            .then(res => {
                if (res.ok) {
                    alert("생성이 완료되었습니다.");
                    navigate(`/day/${dayRef.current.value}`);
                }
            });
    }

    같은 원리로, 날짜 등록도 해보자

     

    CreateDay.js

    export default function CreateDay() {
        const days = useFetch("http://localhost:3001/days");
        const navigate = useNavigate();
    
        function addDay(e) {
            fetch(`http://localhost:3001/days/`, {
                method : 'POST',
                headers : {
                    'Content-Type' : 'application.json'
                },
                body : JSON.stringify({
                    day : days.length + 1
                })
            })
                .then(res => {
                    if (res.ok) {
                        alert("생성이 완료되었습니다.");
                        navigate(`/`);
                    }
                });
        }
    
        return (
            <div>
                <h3>현재 일수 : {days.length}일</h3>
                <button onClick={addDay}>Day 추가</button>
            </div>
        )
    }

     

    화면 

    기능도 모두 정상작동한다.

     

     

    728x90
    반응형

    'Front-End > React' 카테고리의 다른 글

    React 스프링부트와 리액트 연동하기  (3) 2024.09.19
    React RestAPI - 1  (2) 2024.09.03
    React 라우터  (1) 2024.09.02
    React 더미 데이터 생성, map() 반복  (2) 2024.08.31
    React 각 컴포넌트 별 CSS 적용  (0) 2024.08.31
Designed by Tistory.