react+php+mysql

이강민·2022년 12월 27일

react+php

목록 보기
4/4
post-thumbnail

update

update는 게시글을 수정하거나 혹은 조회수를 증가하거나 하는 처리를 할 때 주로 사용된다.

조회수 증가

해당 글을 눌렀을 때 readCnt의 값만 올려주면된다. read를 할때 json에 저장된 readCnt는 문자열로 저장되었으므로 다시 Nunber api를 이용하여 형변환을 해주어야 값을 정상적으로 증가시킬 수 있다.

updateReadCnt.php
<?php
include_once "dbconn.php";
$boardId = $_POST['boardId'];
$readCnt = $_POST['readCnt'];
mysqli_query($connect, "UPDATE board SET readCnt = '$readCnt' WHERE id = '$boardId'")
  ?>
import React from "react";
import { useEffect } from "react";
import { useLocation, useNavigate } from "react-router-dom";

export default function ReadDetail() {
  const navigate = useNavigate();
  const { state: data } = useLocation();
  const deleteHandler = (e) => {
    const formData = new FormData();
    const filePath = data.fileUrl.substr(1);
    console.log(filePath);
    formData.append("boardId", e.target.id);
    formData.append("filePath", filePath);
    if (window.confirm("정말 삭제하시겠습니까?")) {
      fetch("/deleteData.php", {
        method: "POST",
        body: formData,
      })
        .then(() => {})
        .catch((err) => {
          console.log(err, "초기 화면 돌아가기");
        });
      fetch("/fileDelete.php", {
        method: "POST",
        body: formData,
      })
        .then((RES) => {
          console.log(RES);
        })
        .finally(() => {
          navigate("/read");
        })
        .catch((err) => {
          console.log(err, "초기 화면 돌아가기");
        });
    }
  };
  useEffect(() => {
    const formData = new FormData();
    formData.append("boardId", data.id);
    //read를 통해 가져온 값에 1을 증가하면 조회수가 증가된다.
    //가져온 값을 형변환하고 연산시켜 주자 
    formData.append("readCnt", Number(data.readCnt) + 1);
    fetch("/updateReadCnt.php", {
      method: "POST",
      body: formData,
    })
      .then((RES) => {
        console.log(RES);
      })
      .catch((err) => {
        console.log(err, "초기 화면 돌아가기");
      });
  }, [data.id, data.readCnt]);

  const editHandler = () => {
    navigate("readEdit", { state: data });
  };
  const listHandlr = () => {
    navigate("/read");
  };
  return (
    <table>
      <thead>
        <tr>
          <th>날짜</th>
          <th>제목</th>
          <th>내용</th>
          <th>조회수</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>{data.date}</td>
          <td>{data.title}</td>
          <td>{data.content}</td>
          <td>{data.readCnt}</td>
        </tr>
        <tr>
          <td colSpan={4}>
            <img src={data.fileUrl} alt="" />
          </td>
          <td></td>
          <td></td>
          <td></td>
        </tr>
      </tbody>
      <tfoot>
        <button onClick={deleteHandler} id={data.id}>
          삭제
        </button>
        <button onClick={editHandler}>수정</button>
        <button onClick={listHandlr}>목록</button>
      </tfoot>
    </table>
  );
}

게시글 수정하기

updateContent.php
<?php
include_once "dbconn.php";
$boardId = $_POST['boardId'];
$title = $_POST['title'];
$content = $_POST['content'];
$fileUrl = $_POST['fileUrl'];
mysqli_query($connect, "UPDATE board SET title = '$title',content = '$content', fileUrl = '$fileUrl' WHERE id = '$boardId'")
  ?>
import React, { useEffect, useState } from "react";
import moment from "moment";
import { useLocation, useNavigate } from "react-router-dom";
import imageCompression from "browser-image-compression";

export default function ReadEdit() {
  const navigate = useNavigate();
  const [now, setNow] = useState("");
  const [file, setFile] = useState("");
  const [fileName, setFileName] = useState("");
  const [fileUrl, setFileUrl] = useState("");
  const { state: data } = useLocation();
  useEffect(() => {
    //수정시간을 state에 저장
    setNow(moment().format("YYYYMMDD HH:mm:ss"));
  }, []);
  //파일, 이미지 처리
  useEffect(() => {
    const arr = file?.name?.split(".");
    arr && setFileName(data.id + "." + arr[1]);
  }, [file, data.id]);
  useEffect(() => {
    if (file?.type?.includes("image")) {
      setFileUrl("/data/images/" + fileName);
    } else {
      setFileUrl("/data/files/" + fileName);
    }
  }, [fileName, file.type]);
  const fileSetting = (e) => {
    setFile(e.target.files[0]);
  };
  const handleSubmit = (e) => {
    e.preventDefault();
    let formElem = document.getElementById("formdata");
    fetch("/updateContent.php", {
      method: "POST",
      body: new FormData(formElem),
    })
      .then((res) => {
        console.log(res);
      //기존파일을 제거한다.
        originFileDelte();
        if (res.ok === false) {
          alert("연결이 원활하지 않습니다.");
          navigate("/");
        } else if (res.ok) {
          alert("저장되었습니다.");
          navigate("/read");
        }
      })
      .catch(() => {
        console.log("초기 화면 돌아가기");
      });
    const options = {
      maxSizeMB: 0.2,
      maxWidthOrHeight: 800,
      useWebWorker: true,
    };
	//새로운 파일을 저장한다.
    // 새로운 파일은 filesender.php를 재활용한다.
    const formData = new FormData();
    if (file.type.includes("image")) {
      imageCompression(file, options)
        .then((v) => {
          formData.append("userfile", v);
          formData.append("fileImg", v.name);
          formData.append("fileName", fileName);
        })
        .then(() => {
          console.log(formData);
          fetch("/filesender.php", {
            method: "POST",
            body: formData,
          })
            .then((RES) => {
              console.log(RES);
            })
            .catch(() => {
              console.log("초기 화면 돌아가기");
            });
        });
    } else {
      formData.append("userfile", file);
      formData.append("fileName", fileName);
      fetch("/filesender.php", {
        method: "POST",
        body: formData,
      })
        .then((RES) => {
          console.log(RES);
        })
        .catch(() => {
          console.log("초기 화면 돌아가기");
        });
    }
  };
  //기존파일을 제거하는 함수
  const originFileDelte = () => {
    const formData = new FormData();
    const originFilePath = data.fileUrl.substr(1);
    formData.append("filePath", originFilePath);
    fetch("/fileDelete.php", {
      method: "POST",
      body: formData,
    })
      .then((RES) => {
        console.log(RES);
      })
      .finally(() => {
        navigate("/read");
      })
      .catch((err) => {
        console.log(err, "초기 화면 돌아가기");
      });
  };
  return (
    <div>
      <form onSubmit={handleSubmit} id="formdata">
        <p>
          <input type="text" name="boardId" value={data.id} hidden />
        </p>
        <p>
          <input type="text" name="date" value={now} placeholder="작성 일" />
        </p>
        <p>
          <input type="text" name="fileUrl" value={fileUrl} hidden />
        </p>
        <p>
          <input type="text" name="title" placeholder={data.title} required />
        </p>
        <p>
          <textarea
            name="content"
            placeholder={data.content}
            required
          ></textarea>
        </p>
        <p>
          <input type="hidden" name="MAX_FILE_SIZE" value="300000000" />
          <input
            id="userfile"
            name="userfile"
            type="file"
            accept="*"
            onChange={fileSetting}
            required
          />
        </p>
        <p>
          <input type="submit" value={"수정하기"} />
        </p>
      </form>
    </div>
  );
}
profile
AllTimeDevelop

0개의 댓글