개인 프로젝트/블로그

카테고리 달기 (react)

공주맛밤 2022. 7. 10. 14:51

카테고리를 저장하고 이를 다시 boardSaveForm으로 전달 할 때 조금씩의 변경사항들이 있어 그냥 코드 복붙하고 실행결과만 기록

<categoryNameList>

public class CategoryNameList {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String categoryName;

    private Long lcId; //(largeCategoryId)

    private Long scId; //(subCategoryId)

    @Enumerated(EnumType.STRING)
    private CategoryType categoryType;

}

<board>

public class Board { // 보드에 담길 내용: 제목, 내용, 댓글, (글은 나만 쓸 것이므로 유저정보는 필요 없음)

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String title;

    @Lob
    private String content;

    @ManyToOne
    @JoinColumn(name = "subCategory_id")
    @JsonIgnoreProperties(value = {"largeCategory", "boards"})
    private SubCategory subCategory;

    @CreationTimestamp
    private Timestamp createDate;
}

<boardSaveForm>

import { React, useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";
import { Form, Button } from "react-bootstrap";

const SaveForm = () => {
  const navigate = useNavigate();

  const [board, setBoard] = useState({
    title: "",
    content: "",
    subCategory_id: "",
  });

  const [categories, setCategories] = useState([]); //카테고리 받아 올 곳 초기화
  const [largeCategoryId, setLargeCategoryId] = useState(""); //selection으로 부터 값을 받음

  const selectLC = (e) => {
    //largeCategory id값을 넘겨줌
    setLargeCategoryId(e.target.value);
  };

  useEffect(() => {
    fetch("http://localhost:8080/categoryNameList")
      .then((res) => res.json())
      .then((res) => {
        setCategories(res.data); //공백에 가져온 정보로 채워줌
      });
  }, []);

  const changeValue = (e) => {
    setBoard((board) => ({
      ...board,
      [e.target.name]: e.target.value,
    }));
  };

  const submitBoard = (e) => {
    e.preventDefault(); //submit이 액션을 안타고 할 일을 그만함
    console.log(board);
    fetch("http://localhost:8080/api/board/save", {
      method: "post",
      headers: {
        "Content-Type": "application/json; charset=utf-8",
      },
      body: JSON.stringify(board),
    })
      .then((res) => {
        if (res.status === 200) {
          return res.json;
        } else {
          return null;
        }
      })
      .then((res) => {
        if (res !== null) {
          navigate("/"); //글 등록 후 이전 페이지로
        } else {
          alert("글 등록 실패!");
        }
      });
  };

  return (
    <Form onSubmit={submitBoard}>
      <Form.Group className="mb-3" controlId="formGroupTitle">
        <Form.Label>Title</Form.Label>
        <Form.Control
          type="title"
          placeholder="Title..."
          onChange={changeValue}
          name="title"
        />
      </Form.Group>
      <hr />
      <Form.Select size="sm" onChange={selectLC}>
        <option>Large Category</option>
        {categories
          .filter((category) => category.categoryType === "LARGE") //largeCategory 리스트가 출력됨
          .map((category) => {
            return (
              <option key={category.id} value={category.lcId}>
                {category.categoryName}
              </option>
            );
          })}
      </Form.Select>
      <Form.Select size="sm" onChange={changeValue} name="subCategory_id">
        <option>Sub select</option>
        {categories
          .filter(
            (category) =>
              category.categoryType === "SUB" &&
              String(category.lcId) === largeCategoryId
          )
          .map((category) => {
            return (
              <option key={category.id} value={category.scId}>
                {category.categoryName}
              </option>
            );
          })}
      </Form.Select>
      <br />
      <Form.Group className="mb-3" controlId="formGroupContent">
        <Form.Label>Content</Form.Label>
        <Form.Control
          type="content"
          placeholder="Content..."
          onChange={changeValue}
          name="content"
        />
      </Form.Group>
      <hr />
      <br />
      <Button variant="outline-secondary" type="submit">
        저장하기
      </Button>
    </Form>
  );
};

export default SaveForm;

<결과>

largeCategory를 미선택시 subCategory의 option이 없음
공부 카테고리를 선택하면 해당하는 subCategory선택지가 나옴

<contentForm>

import React, { useEffect, useState } from "react";
import { useNavigate, useParams } from "react-router-dom";
import { Button, Card } from "react-bootstrap";

const Content = () => {
  const propsParam = useParams();
  const id = propsParam.id;
  const navigate = useNavigate();

  const [board, setBoard] = useState({
    //처음에 공백
    data: [],
    status: "",
  });

  const [subCategoryName, setSubCategoryName] = useState({});

  useEffect(() => {
    fetch("http://localhost:8080/board/" + id) //id를 통해서 게시판 정보를 가져옴
      .then((res) => res.json())
      .then((res) => {
        setBoard(res); //공백에 가져온 정보로 채워줌
        setSubCategoryName(res.data.subCategory);
      });
  }, [id]);

  const deleteBoard = () => {
    //해당 게시글 삭제
    fetch("http://localhost:8080/api/board/" + id + "/delete", {
      method: "DELETE",
    })
      .then((res) => res.text())
      .then((res) => {
        if (res === "success delete!") {
          navigate("/");
        } else {
          alert("삭제 실패");
        }
      });
  };

  const updateBoard = () => {
    //함수 updateBoard 실행되면 /update/id로 이동
    navigate("/board/updateForm/" + id);
  };

  return (
    <div>
      <h1>{board.data.title}</h1>
      <Button variant="secondary" onClick={() => updateBoard()}>
        수정
      </Button>{" "}
      <Button variant="secondary" onClick={() => deleteBoard()}>
        삭제
      </Button>
      <hr />
      <Card>
        <Card.Body>Category: {subCategoryName.subCategoryName}</Card.Body>
      </Card>
      <Card>
        <Card.Body>{board.data.content}</Card.Body>
      </Card>
      <Button variant="secondary" onClick={() => navigate(-1)}>
        돌아가기
      </Button>
    </div>
  );
};

export default Content;
카테고리도 board에 저장된 것이 제대로 나옴

<updateForm>

@Transactional
public Board boardUpdate(Long id, BoardSaveDto boardSaveDto) { //게시글 수정 PutMapping
    Board boardEntity = boardRepository.findById(id) //더티 체킹(DB가 변화를 감지해서 update문 실행)
            .orElseThrow(() -> new IllegalArgumentException("이미 삭제된 게시글 입니다."));

    SubCategory subCategory = subCategoryRepository.findById(boardSaveDto.getSubCategory_id())
            .orElseThrow(() -> new IllegalArgumentException("없는 카테고리 입니다."));

    boardEntity.setSubCategory(subCategory);
    boardEntity.setTitle(boardSaveDto.getTitle());
    boardEntity.setContent(boardSaveDto.getContent());
    return boardEntity;
}
import React, { useEffect, useState } from "react";
import { useNavigate, useParams } from "react-router-dom";
import { Form, Button } from "react-bootstrap";

const UpdateForm = () => {
  const navigate = useNavigate();

  const propsParam = useParams();
  const id = propsParam.id;

  const [board, setBoard] = useState({
    //update할 게시글의 데이터를 받아옴
    data: [],
    status: "",
  });

  const [categories, setCategories] = useState([]); //카테고리 받아 올 곳 초기화
  const [largeCategoryId, setLargeCategoryId] = useState(""); //selection으로 부터 값을 받음

  const selectLC = (e) => {
    //largeCategory id값을 넘겨줌
    setLargeCategoryId(e.target.value);
  };

  useEffect(() => {
    fetch("http://localhost:8080/categoryNameList")
      .then((res) => res.json())
      .then((res) => {
        setCategories(res.data); //공백에 가져온 정보로 채워줌
      });
  }, []);

  useEffect(() => {
    fetch("http://localhost:8080/board/" + id) //update할 게시글의 데이터를 받아옴
      .then((res) => res.json())
      .then((res) => {
        setBoard(res);
      });
  }, [id]);

  const changeValue = (e) => {
    setBoard((prevState) => ({
      ...prevState,
      data: {
        ...prevState.data,
        [e.target.name]: e.target.value,
      },
    }));
  };

  const submitBoard = (e) => {
    e.preventDefault();
    fetch("http://localhost:8080/api/board/" + id + "/update", {
      method: "PUT",
      headers: {
        "Content-Type": "application/json; charset=utf-8",
      },
      body: JSON.stringify(board.data),
    })
      .then((res) => {
        if (res.status === 200) {
          return res.json;
        } else {
          return null;
        }
      })
      .then((res) => {
        if (res !== null) {
          navigate(-1); //글 등록 후 이전 페이지로
        } else {
          alert("글 수정 실패!");
        }
      });
  };

  return (
    <div>
      <h1>글 수정 </h1>
      <Form onSubmit={submitBoard}>
        <Form.Group className="mb-3" controlId="formGroupTitle">
          <Form.Label>Title</Form.Label>
          <Form.Control
            type="title"
            placeholder="Title..."
            onChange={changeValue}
            name="title"
            value={board.data.title || ""}
          />
        </Form.Group>
        <hr />
        <Form.Select size="sm" onChange={selectLC}>
          <option>Large Category</option>
          {categories
            .filter((category) => category.categoryType === "LARGE") //largeCategory 리스트가 출력됨
            .map((category) => {
              return (
                <option key={category.id} value={category.lcId}>
                  {category.categoryName}
                </option>
              );
            })}
        </Form.Select>
        <Form.Select size="sm" onChange={changeValue} name="subCategory_id">
          <option>Sub Category</option>
          {categories
            .filter(
              (category) =>
                category.categoryType === "SUB" &&
                String(category.lcId) === largeCategoryId
            )
            .map((category) => {
              return (
                <option key={category.id} value={category.scId}>
                  {category.categoryName}
                </option>
              );
            })}
        </Form.Select>
        <hr />
        <Form.Group className="mb-3" controlId="formGroupContent">
          <Form.Label>Content</Form.Label>
          <Form.Control
            type="content"
            placeholder="Content..."
            onChange={changeValue}
            name="content"
            value={board.data.content || ""}
          />
        </Form.Group>
        <hr />
        <br />
        <Button variant="outline-secondary" type="submit">
          저장하기
        </Button>
      </Form>
    </div>
  );
};

export default UpdateForm;

수정 결과

728x90
반응형

'개인 프로젝트 > 블로그' 카테고리의 다른 글

refresh 토큰 후처리 고민  (0) 2022.07.17
로그인 구현 생각  (0) 2022.07.10
카테고리 이름 리스트 적용기(벡엔드)  (0) 2022.07.09
게시글 category 적용 고민  (0) 2022.07.08
카타고리 달기 (front)  (0) 2022.07.08