十七、修改数据

郁子大约 2 分钟约 484 字笔记React18李立超

(一) src/components/Student/index.jsx

import React, { useCallback, useContext, useState } from "react";
import StudentContext from "../../store/StudentContext";
import StudentForm from "../StudentForm";

const Student = ({
  stu: {
    id,
    attributes: { name, age, gender, address },
  },
  stu,
}) => {
  /*
    props = {
      stu: {
        id: xxx,
        attributes: {
          name,age,gender,address
        }
      }
    }
  */

  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);
  const [editing, setEditing] = useState(false);
  const ctx = useContext(StudentContext);

  const delStu = useCallback(async () => {
    try {
      setLoading(true);
      setError(null);
      const res = await fetch(`http://localhost:1337/api/students/${id}`, {
        method: "delete",
      });
      if (!res.ok) throw new Error("删除失败!");
      ctx.fetchData();
    } catch (error) {
      setError(error);
    } finally {
      setLoading(false);
    }
  }, [id, ctx]);

  const deleteStudent = () => {
    delStu();
  };

  const cancelEdit = () => {
    setEditing(false);
  };

  return (
    <>
      {!editing && (
        <tr>
          <td>{name}</td>
          <td>{gender}</td>
          <td>{age}</td>
          <td>{address}</td>
          <td>
            <button onClick={deleteStudent}>删除</button>
            <button onClick={() => setEditing(true)}>修改</button>
          </td>
        </tr>
      )}

      {editing && <StudentForm stu={stu} onCancelEdit={cancelEdit} />}

      {loading && (
        <tr>
          <td colSpan={5}>正在删除数据...</td>
        </tr>
      )}
      {error && (
        <tr>
          <td colSpan={5}>删除失败!</td>
        </tr>
      )}
    </>
  );
};

export default Student;

(二) src/components/StudentForm/index.jsx

import React, { useCallback, useContext, useState } from "react";
import StudentContext from "../../store/StudentContext";
import "./index.css";

const StudentForm = (props) => {
  const ctx = useContext(StudentContext);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);
  const [inputData, setInputData] = useState({
    name: props.stu ? props.stu.attributes.name : "",
    gender: props.stu ? props.stu.attributes.gender : "男",
    age: props.stu ? props.stu.attributes.age : 0,
    address: props.stu ? props.stu.attributes.address : "",
  });
  const { name, gender, age, address } = inputData;

  const nameChange = (e) => {
    setInputData((pre) => ({ ...pre, name: e.target.value }));
  };
  const genderChange = (e) => {
    setInputData((pre) => ({ ...pre, gender: e.target.value }));
  };
  const ageChange = (e) => {
    setInputData((pre) => ({ ...pre, age: +e.target.value }));
  };
  const addressChange = (e) => {
    setInputData((pre) => ({ ...pre, address: e.target.value }));
  };

  const addStudent = useCallback(
    async (newStudent) => {
      try {
        setLoading(true);
        setError(null);
        const res = await fetch("http://localhost:1337/api/students/", {
          method: "post",
          body: JSON.stringify({
            data: newStudent,
          }),
          headers: {
            "Content-type": "application/json",
          },
        });
        if (!res.ok) throw new Error("添加失败!");
        ctx.fetchData();
      } catch (error) {
        setError(error);
      } finally {
        setLoading(false);
      }
    },
    [ctx],
  );
  const onSubmitAdd = () => {
    addStudent(inputData);
  };

  const editStudent = useCallback(
    async (id, newStudent) => {
      try {
        setLoading(true);
        setError(null);
        const res = await fetch(`http://localhost:1337/api/students/${id}`, {
          method: "put",
          body: JSON.stringify({
            data: newStudent,
          }),
          headers: {
            "Content-type": "application/json",
          },
        });
        if (!res.ok) throw new Error("添加失败!");
        ctx.fetchData();
      } catch (error) {
        setError(error);
      } finally {
        setLoading(false);
      }
    },
    [ctx],
  );
  const onSubmitEdit = () => {
    editStudent(props.stu.id, inputData);
  };

  return (
    <>
      <tr className="student-form">
        <td>
          <input type="text" value={name} onChange={nameChange} />
        </td>
        <td>
          <select value={gender} onChange={genderChange}>
            <option value="男"></option>
            <option value="女"></option>
          </select>
        </td>
        <td>
          <input type="text" value={age} onChange={ageChange} />
        </td>
        <td>
          <input type="text" value={address} onChange={addressChange} />
        </td>
        <td>
          {props.stu && (
            <>
              <button onClick={() => props.onCancelEdit()}>取消</button>
              <button onClick={onSubmitEdit}>确认</button>
            </>
          )}
          {!props.stu && <button onClick={onSubmitAdd}>添加</button>}
        </td>
      </tr>
      {loading && (
        <tr>
          <td colSpan={5}>添加中...</td>
        </tr>
      )}
      {error && (
        <tr>
          <td colSpan={5}>添加失败!</td>
        </tr>
      )}
    </>
  );
};

export default StudentForm;
上次编辑于: