Certainly! Let’s create separate components for better organization and maintainability. We’ll create components for StudentForm, StudentList, and StudentItem. The App component will be responsible for managing the state and rendering these components.

Here’s the updated project structure:

  1. Create a new file StudentForm.js:
// StudentForm.js
import React from 'react';

function StudentForm({ onSubmit, onChange, values, isEditing, onCancel }) {
  return (
    <div>
      {isEditing ? (
        <>
          <input
            type="text"
            placeholder="Student Name"
            value={values.name}
            onChange={(e) => onChange({ ...values, name: e.target.value })}
          />
          <input
            type="text"
            placeholder="Student Age"
            value={values.age}
            onChange={(e) => onChange({ ...values, age: e.target.value })}
          />
          <button onClick={onSubmit}>Update</button>
          <button onClick={onCancel}>Cancel</button>
        </>
      ) : (
        <>
          <input
            type="text"
            placeholder="Student Name"
            value={values.name}
            onChange={(e) => onChange({ ...values, name: e.target.value })}
          />
          <input
            type="text"
            placeholder="Student Age"
            value={values.age}
            onChange={(e) => onChange({ ...values, age: e.target.value })}
          />
          <button onClick={onSubmit}>Add Student</button>
        </>
      )}
    </div>
  );
}

export default StudentForm;
  1. Create a new file StudentList.js:
// StudentList.js
import React from 'react';
import StudentItem from './StudentItem';

function StudentList({ students, onEdit, onDelete }) {
  return (
    <ul>
      {students.map((student) => (
        <StudentItem
          key={student.id}
          student={student}
          onEdit={onEdit}
          onDelete={onDelete}
        />
      ))}
    </ul>
  );
}

export default StudentList;
  1. Create a new file StudentItem.js:
// StudentItem.js
import React from 'react';

function StudentItem({ student, onEdit, onDelete }) {
  return (
    <li>
      {`${student.name} (Age: ${student.age})`}
      <button onClick={() => onEdit(student.id)}>Edit</button>
      <button onClick={() => onDelete(student.id)}>Delete</button>
    </li>
  );
}

export default StudentItem;
  1. Update App.js:
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import StudentForm from './StudentForm';
import StudentList from './StudentList';

const API_URL = 'https://jsonplaceholder.typicode.com/users';

function App() {
  const [students, setStudents] = useState([]);
  const [newStudent, setNewStudent] = useState({
    name: '',
    age: '',
  });
  const [editing, setEditing] = useState(false);
  const [editStudent, setEditStudent] = useState({
    id: null,
    name: '',
    age: '',
  });

  useEffect(() => {
    fetchData();
  }, []);

  const fetchData = async () => {
    try {
      const response = await axios.get(API_URL);
      setStudents(response.data);
    } catch (error) {
      console.error('Error fetching data:', error);
    }
  };

  const addStudent = async () => {
    try {
      const response = await axios.post(API_URL, {
        name: newStudent.name,
        age: newStudent.age,
      });
      setStudents([...students, response.data]);
      setNewStudent({ name: '', age: '' });
    } catch (error) {
      console.error('Error adding student:', error);
    }
  };

  const deleteStudent = async (id) => {
    try {
      await axios.delete(`${API_URL}/${id}`);
      setStudents(students.filter((student) => student.id !== id));
    } catch (error) {
      console.error('Error deleting student:', error);
    }
  };

  const startEditing = (id) => {
    const studentToEdit = students.find((student) => student.id === id);
    setEditing(true);
    setEditStudent({ ...studentToEdit });
  };

  const cancelEditing = () => {
    setEditing(false);
    setEditStudent({ id: null, name: '', age: '' });
  };

  const updateStudent = async () => {
    try {
      await axios.put(`${API_URL}/${editStudent.id}`, {
        name: editStudent.name,
        age: editStudent.age,
      });
      setStudents(
        students.map((student) =>
          student.id === editStudent.id ? editStudent : student
        )
      );
      setEditing(false);
      setEditStudent({ id: null, name: '', age: '' });
    } catch (error) {
      console.error('Error updating student:', error);
    }
  };

  return (
    <div>
      <h1>Student Management</h1>
      <StudentForm
        onSubmit={editing ? updateStudent : addStudent}
        onChange={setEditing ? setEditStudent : setNewStudent}
        values={editing ? editStudent : newStudent}
        isEditing={editing}
        onCancel={cancelEditing}
      />
      <StudentList
        students={students}
        onEdit={startEditing}
        onDelete={deleteStudent}
      />
    </div>
  );
}

export default App;

Now, the logic for managing the form, list, and list items are separated into their respective components. This makes the code more modular and easier to maintain.

Tagged in:

,