리액트 게시판 만들기

hhkim·2021년 8월 7일
6
post-thumbnail

🔗 react-board 완성본

리액트로 DB 없이 로컬 스토리지를 사용하여 간단한 게시판 만들어보기~! (feat. 라우터)


프로젝트 세팅

  • create-react-app 프로젝트 생성
    npx create-react-app react-board
  • react-router-dom 설치
    npm install react-router-dom

구조

  • 라우터를 사용하여 각 페이지를 라우팅
  • Board
    • List
      • 글쓰기 버튼
      • ListItem
        • 글 제목, 날짜, 조회수 출력
    • Write
      • 글쓰기
      • 제목, 내용 폼
      • 작성, 취소 버튼
    • Update
      • 수정
      • 제목, 내용 폼
      • 작성, 취소 버튼
    • Detail
      • 제목, 날짜, 조회수, 내용 출력
      • 목록 버튼

개념 정리

라우팅하는 컴포넌트에 props 전달하기

  • Routecomponent 속성 대신 render 속성을 사용한다. (참고)
<Route path="/write" render={() => <Write addListItem={addListItem} />} />
  • 단, 이렇게 props를 전달하면 기존 라우트 props(match, location, history)를 잃기 때문에 필요하면 매개변수로 받아서 전달해주어야 한다.
<Route path="/write" render={(routeProps) => <Write addListItem={addListItem} {...routeProps} />} />

경로 매개변수 :(route parameter)

  • 글을 조회할 때 /detail/글번호 형식의 주소를 주고 싶었는데, 이걸 경로 매개변수를 사용해서 동적으로 라우팅할 수 있다. (참고)
<Route path="/update/:id" component={Update} />
  • 이렇게 주어진 매개변수는 props.match.params.id로 접근할 수 있다.

함수 내에서 라우팅 경로로 이동하기

  • props로 전달된 history 객체를 이용한다.
history.push(`/detail/${id}`);
  • props를 전달하려면 state에 값을 전달한다. (참고)

JSX에서 텍스트 개행 처리

  • textarea에 내용을 입력하고 로컬 스토리지에 저장하면 개행문자가 함께 저장되지만, 리액트에서는 보안상의 이유로 렌더링 시에 이를 무시한다고 한다. (개행이 안 됨)
  • CSS의 white-spacepre-wrap 옵션을 주어 처리한다.(참고)
<div style={{ whiteSpace: 'pre-wrap' }}>{content}</div>

커스텀 훅

  • Write와 Update의 인풋 value를 바꾸어주는 중복되는 함수가 많아서 커스텀 훅을 만들었다.
// useInputs.js
import { useReducer } from 'react';

function reducer(state, action) {
  return {
    ...state,
    [action.name]: action.value,  // e.target의 name과 value
  };
}

export default function useInputs(initialState) {
  const [state, dispatch] = useReducer(reducer, initialState);
  const onChangeInput = (e) => {
    dispatch(e.target);
  };
  return [state, onChangeInput];
}
// Write.js
...
import useInputs from '../useInputs';
...

const Write = ({ addListItem, id, history }) => {
  const [state, onChangeInput] = useInputs({ title: '', content: '' });
  const { title, content } = state;
  ...

  return (
    <div>
      <h1>write</h1>
      <form onSubmit={onSubmitForm}>
        <input
          ref={inputTitle}
          placeholder="title"
          name="title"
          value={title}
          onChange={onChangeInput}
        />
        ...
    </div>
  );
};

useReducer()

  • 컴포넌트에 전달하는 props가 늘어나면서 정리할 필요성도 느꼈고 useReducer() 쓰는 것도 연습할 겸 코드를 리팩토링해보았다.

함수가 두 번 실행되는 문제

  • 언제부터인지 조회수가 2씩 늘어났다... 아무리 콘솔을 찍어봐도 문제를 알 수 없고 함수 컴포넌트 렌더링도 두 번씩 되고 있었고...
  • 검색을 해봤더니 React.StrictMode에서 성능 테스트를 위해 의도적으로 개발 모드에서만 두 번 호출하는 함수들이 있다고 한다. StrictMode를 지웠더니 문제 해결! (참고)

코드 작성

🔗 깃헙


참고

https://ing-yeo.net/2020/10/react-beginner-5/

3개의 댓글

comment-user-thumbnail
2024년 4월 2일

안녕하세요!
제가 Spring boot와 react를 연동한 게시판을 만들고 있는데 블로그장님의 디자인이 이뻐서 css를 참고해서 만들었습니다!
제가 만든 게시판을 git이랑 블로그에 올려고 하는데 출처는 남길 예정입니다!
올리기 전에 허락을 먼저 구해야할 것 같아 이렇게 댓 작성합니다.
확인 후 답 주세요!

2개의 답글