Выбор одной строки в таблице без использования дополнительных пакетов npm

#reactjs

#reactjs

Вопрос:

Я пытаюсь создать повторно используемую таблицу с нуля без использования дополнительных пакетов npm. Проблема, которую я пытался решить весь день, заключается в выборе одной строки при щелчке флажка. Я хотел добиться этого, изменив имя класса на «синий» при изменении состояния. className={selectValue ? "blue" : null} Что происходит прямо сейчас, так это то, какую бы строку я ни выбрал, она выбирает все строки. Я надеялся, что вы сможете указать мне правильное направление. Каковы другие способы изменения цвета фона при нажатии флажка?

Я ценю помощь.

Код и Codesandbox ниже.

https://codesandbox.io/s/friendly-resonance-48iu3?file=/src/App.js

 import React, { useState, useEffect } from "react";
import "../../App.css";

function Student() {
  const [studentState, setStudentState] = useState([]);
  const [selectValue, setSelectValue] = useState("");

  useEffect(() => {
    let studentState = [
      { id: 1, firstname: "Stone", lastname: "Cold", major: "wwf" },
      { id: 2, firstname: "Addrian", lastname: "Fox", major: "wwf" },
      { id: 3, firstname: "Harry", lastname: "Pit", major: "wwf" },
    ];

    setStudentState(
      studentState.map((d) => {
        return {
          select: false,
          id: d.id,
          firstname: d.firstname,
          lastname: d.lastname,
          major: d.major,
        };
      })
    );
  }, []);


  return (
    <div className="container">
      <table className="table table-bordered">
        <thead>
          <tr>
            <th scope="col">
              <input
                type="checkbox"
                onChange={(e) => {
                  let checked = e.target.checked;
                  setStudentState(
                    studentState.map((d) => {
                      d.select = checked;
                      return d;
                    })
                  );
                  
                }}
              ></input>
            </th>
            <th scope="col">First</th>
            <th scope="col">Last</th>
            <th scope="col">Handle</th>
          </tr>
        </thead>
        <tbody>
          {studentState.map((d, i) => (
            <tr key={d.id} className={selectValue ? "blue" : null}>
              <th scope="row">
                <input
                  onChange={(event) => {
                    let checked = event.target.checked;
                    setStudentState(
                      studentState.map((data) => {
                        if (d.id === data.id) {
                          data.select = checked;
                        }
                        return data;
                      })
                    );
                    setSelectValue(checked)
                  }}
                  type="checkbox"
                  checked={d.select}
                  id={d.id}
                ></input>
              </th>
              <td>{d.firstname}</td>
              <td>{d.lastname}</td>
              <td>{d.major}</td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}

export default Student;

  

Ответ №1:

вы используете одно состояние для проверки выбранной строки, что невозможно сделать, поскольку одно состояние не может содержать значение для всех строк. Я вижу, что у вас также есть статус select внутри каждого объекта, который вы используете для установки / снятия флажков. Мы можем использовать то же самое для отображения цветных строк. Вот обновленный codesandbox, на который вы можете взглянуть. Дайте мне знать, если возникнут какие-либо вопросы.

 export default function App() {
  const [studentState, setStudentState] = useState([]);

  useEffect(() => {
    let studentState = [
      { id: 1, firstname: "Stone", lastname: "cold", major: "wwf" },
      { id: 2, firstname: "Addrian", lastname: "Fox", major: "wwf" },
      { id: 3, firstname: "Harry", lastname: "Pit", major: "wwf" }
    ];

    setStudentState(
      studentState.map((d) => {
        return {
          select: false,
          id: d.id,
          firstname: d.firstname,
          lastname: d.lastname,
          major: d.major
        };
      })
    );
  }, []);

  return (
    <div className="container">
      <table className="table table-bordered">
        <thead>
          <tr>
            <th scope="col">
              <input
                type="checkbox"
                onChange={(e) => {
                  let checked = e.target.checked;
                  setStudentState(
                    studentState.map((d) => {
                      d.select = checked;
                      return d;
                    })
                  );
                }}
              ></input>
            </th>
            <th scope="col">First</th>
            <th scope="col">Last</th>
            <th scope="col">Handle</th>
          </tr>
        </thead>
        <tbody>
          {studentState.map((d, i) => (
            <tr key={d.id} className={d.select ? "blue" : null}>
              <th scope="row">
                <input
                  onChange={(event) => {
                    let checked = event.target.checked;
                    setStudentState(
                      studentState.map((data) => {
                        if (d.id === data.id) {
                          data.select = checked;
                        }
                        return data;
                      })
                    );
                  }}
                  type="checkbox"
                  checked={d.select}
                  id={d.id}
                ></input>
              </th>
              <td>{d.firstname}</td>
              <td>{d.lastname}</td>
              <td>{d.major}</td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}
  

Комментарии:

1. Вау, я не могу поверить, что пропустил это, ха-ха. Замечательно. Я ценю помощь и советы. Большое вам спасибо