[React] 내가 작성한 글, 댓글 서버에 저장시키기

김유진·2022년 7월 7일
1

React

목록 보기
15/64
post-custom-banner

1. 내가 작성한 글 서버에 넘기기

글 작성에 대한 API를 확인하고, 이에 맞추어서 한번 React 코드를 작성하여 보자!

요청

https://reactapitest.pythonanywhere.com/api/posts/

이 곳의 API에 우리가 작성한 글을 보내게 될 것이고,
요청 방식은 Post이다.
우리가 넘겨주게 될 데이터의 형식은 다음과 같다.

{
    "title": " 찬성을 얻은 때",
    "contents": "모든 국민은 종교의 자유를 가진다. 헌법개정안이 제2항의 찬성을 얻은 때에는 헌법개정은 확정되며, 대통령은 즉시 이를 공포하여야 한다. 대통령은 조약을 체결·비준하고, 외교사절을 신임·접수 또는 파견하며, 선전포고와 강화를 한다.한다..",
    "repls":[]
}

그리고 응답은 다음과 같이 오게 되겠지.

{
    "id": 23,
    "title": "찬성을 얻은 때",
    "contents": "모든 국민은 종교의 자유를 가진다. 헌법개정안이 제2항의 찬성을 얻은 때에는 헌법개정은 확정되며, 대통령은 즉시 이를 공포하여야 한다. 대통령은 조약을 체결·비준하고, 외교사절을 신임·접수 또는 파견하며, 선전포고와 강화를 한다.한다..",
    "repls": []
}

이 친구도 똑같이 props로 API의 주소를 넘겨준다.
App.jsx를 수정해보자.

 <Routes>
 	<Route path = "/" element = {<ShowPostList apiUrl = {API_URL}></ShowPostList>}></Route>
	<Route path = "/write" element = {<WritePost apiUrl={API_URL}></WritePost>}></Route>
	<Route path = "/post/:postID" element = {<ShowPost apiUrl={API_URL}></ShowPost>}></Route>
</Routes>

이렇게 수정을 완료하였다! 그리고 마찬가지로, Writepost.jsx에도 props로 해당 API를 넘겨준다.

이 과정은 서버의 글을 바로 우리가 HTTP 요청을 통하여 받아오는 것이 아니라, 글 입력버튼을 눌렀을때 우리가 요청을 보내는 것이다. 그래서 별다른 Hook을 사용하지 않고, handler 함수를 만들어 둘 것이다.

이 함수 작성은 아래 axios 공식 문서에서 POST REQUEST를 보내는 방법을 참고하였다.
https://axios-http.com/docs/post_example

const onSubmit = () => {
   axios.post(`${apiUrl}/posts/`, {
        title : inputs.title,
        contents : inputs.contents,
        repls : [],}).then(response => {
          console.log(response);
    })
}

함수를 만들었다. 우리가 기존에 만들었던 inputs 데이터 안에

   const [inputs,setInputs] = useState({
       title : '',
       contents :'',
   });
   const {title, contents} = inputs;

얘네가 잘 들어가 있으니까 가지고 와서 이용만 해 주면 된다. 우리는 그리고 빈 배열을 넘길 거니가 repls : []로 넘긴다.
이제 onClick 함수로 연결해보자!

  return (
    <PostSection>
      <WriteTitle/>
      <PostWriteDiv>
        <InputPost 
            onChange = {onChange}
            title = {title}
            contents = {contents}></InputPost>
      </PostWriteDiv>
      <SubmitComponent onSubmit = {onSubmit}></SubmitComponent> 
    </PostSection>
  );
}

우리가 onSubmit의 이름으로 props를 넘겨주고,
PostSubmit이라는 컴포넌트를 클릭할 때 값이 넘겨지게 된다.

const SubmitComponent = React.memo(({onSubmit}) => (
    <PostSubmitDiv>
        <PostSubmit onClick = {onSubmit}>작성완료</PostSubmit>
    </PostSubmitDiv>
));

이렇게 내가 작성하여 작성완료버튼을 눌렀더니, 콘솔에 나의 글에 대한 데이터가 담겨있는 것을 확인할 수 있었다.

2. 글을 작성 완료할 때 리다이렉트 하기

useNavigate를 기억하는지! 이 친구는 navigate라는 값을 반환하여 페이지 간 이동을 할 수 있게끔 만들어 주는 친구이다. 이를 이용하여 글 작성을 완료하였을 때 화면 전환을 해보도록 하자. 작성을 완료하면 HOME으로 돌아가 보도록 하자!

  const navigate = useNavigate();

    const onSubmit = () => {
      axios.post(`${apiUrl}/posts/`, {
        title : inputs.title,
        contents : inputs.contents,
        repls : [],}).then(() => {
          navigate('../');
        })
    }

작성 완료하면 우리가 설정한 홈 화면의 경로인 /으로 넘어가도록 한다.
공식 문서에 따르면 원하는 주소로 가기 전에 ..을 꼭 포함해야 하는 듯!!
당연히 react-router-dom에서 useNavigate를 import한 것이다!

3. 나의 댓글을 넘겨보자!

이 친구들은 다음과 같은 형식으로 정보를 넘겨줄 예정이다.

https://reactapitest.pythonanywhere.com/api/repl/

위는 APi이고, 정보는 다음 형식으로 넘겨줄 것이다.

{
   "contents": "그래 응원해주자!!",
    "post": 1
}

그리고 잘 보내지면 응답은 다음과 같다.

{
   "id": 3,
   "contents": "그래 응원해주자!!",
   "post": 1
}

다음으로 이러한 코드를 작성해보자. 이 핸들러 함수는 댓글을 입력하였을 때, 이를 보내주는 역할을 하는 함수이다.

 const onSubmitRepl = () => {
   axios.post(`${apiUrl}repl/`,{
     contents : repl,
     post : Params.postID,
   }).then((response) => {
     console.log(response.data);
     window.location.reload();
   })
 }

이 때, response.data는 정보가 어떻게 찍히는지 보기 위하여 넣어놓은 것이고 댓글을 작성하면 새로고침을 하도록 만들었는데, React는 SPA 기반으로 작동하기때문에 새로고침을 javascript를 이용하여 해 주었다.
받아온 변수들이 어디에 있는지 한번 확인해보자.

const ShowPost = ({apiUrl}) => {
  const [post, setPost] = useState(null);
  const [repls, setRepls] = useState([]);
  const [postLoading, setPostLoading] = useState(true);
  const [replLoading, setReplLoading] = useState(true);
  const replInput = useRef();
  const Params = useParams();

오호라. 여기 있네요.
이제 버튼에다가 onClick으로 연결해봅시다!

<WriterDiv>
          <ReplInput 
          onChange = {onChange} 
          value = {repl} 
          ref = {replInput}></ReplInput>
          <ReplSubmitDiv onClick = {onSubmitRepl}>
            <span>입력</span>
          </ReplSubmitDiv>
        </WriterDiv>
      </PostSection>
    </div>

짜잔~ 이렇게 연결을 완료하였습니다.
하다가 중간에 에러가 떴는데, 작성한 댓글이 이미 배열로 넘어가는데 코드를 다음과 같이 수정했습니다.

 <ReplTitleDiv>댓글 {replCount} </ReplTitleDiv>
        {replLoading ? (
          <LoadingDiv>
            <LoadingImg src={`${process.env.PUBLIC_URL}/img/loading.svg`} />
          </LoadingDiv>
        ) : (
          repls &&
          repls.map((element) => (
            <PostReplDiv key={element}>
              <ReplWriter>익명</ReplWriter>
              <Repl>{element}</Repl>
            </PostReplDiv>
          ))
        )}

원래는 key = {element.id} 이렇게 받았거든요. 그렇게 했더니 에러가 떠서 element 값을 받아오도록 하였습니다.

내가 작성한 댓글이 입력 버튼을 누르면 잘 넘어가는 것을 알 수 있었다.

post-custom-banner

0개의 댓글