React中动态创建的行中的下拉菜单吗?

问题描述 投票:3回答:1

[我正在动态创建和删除行,而在创建行的同时,我在选择下拉列表时创建了下拉列表,下一个html字段即INPUT LNAME发生了更改。

由于行是动态创建和删除的,所以当我添加新行以及从下拉列表中选择值时,所有html都会在INPUT LNAME中进行更改。而是只更改INPUT LNAME中的该行html,而不更改所有行中的所有html

working code

import React from "react";
import "./styles.css";

export default function App() {
  const [state, setState] = React.useState({
    rows: [{}]
  });

  const handleChange = idx => e => {
    const { name, value } = e.target;
    const rows = [...state.rows];
    rows[idx] = { ...rows[idx], [name]: value }; //here
    setState({
      rows
    });
  };

  const handleAddRow = () => {
    const item = {
      fname: "",
      lname: ""
    };
    setState({
      rows: [...state.rows, item]
    });
  };

  const handleRemoveSpecificRow = idx => () => {
    const rows = [...state.rows];
    rows.splice(idx, 1);
    setState({ rows });
  };

  React.useEffect(() => {
    console.log(state);
  }, [state]);

  const [ddlSelectedid, setDdlSelectedId] = React.useState("");
  console.log(ddlSelectedid);

  const handleSelect = event => {
    setDdlSelectedId(event.target.value);
    setShow(false);
  };

  const [show, setShow] = React.useState(true);
  const selectionContent = idx => {
    if (ddlSelectedid === "INPUT") {
      return (
        <input
          type="text"
          name="lname"
          value={state.rows[idx].name}
          onChange={handleChange(idx)}
        />
      );
    } else if (ddlSelectedid === "RADIO") {
      return (
        <input
          type="radio"
          name="lname"
          value={state.rows[idx].name}
          onChange={handleChange(idx)}
        />
      );
    } else if (ddlSelectedid === "CHECKBOX") {
      return (
        <input
          type="checkbox"
          name="lname"
          value={state.rows[idx].name}
          onChange={handleChange(idx)}
        />
      );
    }
  };

  return (
    <div className="App">
      <table>
        <thead>
          <tr>
            <th>#</th>
            <th>INPUT FNAME</th>
            <th>Dropdown</th>
            <th>INPUT LNAME</th>
            <th>Button</th>
          </tr>
        </thead>
        <tbody>
          {state.rows.map((item, idx) => (
            <tr id="addr0" key={idx}>
              <td>{idx}</td>
              <td>
                <input
                  type="text"
                  name="fname"
                  value={state.rows[idx].name}
                  onChange={handleChange(idx)}
                />
              </td>
              <td>
                <select name="cars" id="cars" onChange={handleSelect}>
                  <option defaultValue="INPUT">INPUT</option>
                  <option value="RADIO">RADIO</option>
                  <option value="CHECKBOX">CHECKBOX</option>
                </select>
              </td>
              <td>
                {show && (
                  <input
                    type="text"
                    name="lname"
                    value={state.rows[idx].name}
                    onChange={handleChange(idx)}
                  />
                )}

                {!show && selectionContent(idx)}
              </td>
              <td>
                <button className="btn" onClick={handleRemoveSpecificRow(idx)}>
                  Remove
                </button>
              </td>
            </tr>
          ))}
        </tbody>
      </table>
      <button onClick={handleAddRow} className="btn">
        Add Row
      </button>
    </div>
  );
}
reactjs
1个回答
0
投票

ddlSelectedidshow添加数组。您在ddlSelectedidshow中分配单个值。当您更改下拉列表时,所有行都会更新。

您可以在此处codesandbox查看工作代码

import React from "react";
import "./styles.css";

export default function App() {
  const [state, setState] = React.useState({
    rows: [{}]
  });

  const handleChange = idx => e => {
    const { name, value } = e.target;
    const rows = [...state.rows];
    rows[idx] = { ...rows[idx], [name]: value }; //here
    setState({
      rows
    });
  };

  const handleAddRow = () => {
    const item = {
      fname: "",
      lname: ""
    };
    setState({
      rows: [...state.rows, item]
    });
    setDdlSelectedId([...ddlSelectedid, "INPUT"]);
    setShow([...show, true]);
  };

  const handleRemoveSpecificRow = idx => () => {
    const rows = [...state.rows];
    rows.splice(idx, 1);
    setState({ rows });
    ddlSelectedid.splice(idx, 1);
    setDdlSelectedId([...ddlSelectedid]);
    show.splice(idx, 1);
    setShow([...show]);
  };

  React.useEffect(() => {
    console.log(state);
  }, [state]);

  const [ddlSelectedid, setDdlSelectedId] = React.useState(["INPUT"]);
  console.log(ddlSelectedid);

  const handleSelect = (event, idx) => {
    event.stopPropagation();
    ddlSelectedid[idx] = event.target.value;
    setDdlSelectedId([...ddlSelectedid]);
    show[idx] = false;
    setShow([...show]);
  };

  const [show, setShow] = React.useState([true]);
  const selectionContent = idx => {
    if (ddlSelectedid[idx] === "INPUT") {
      return (
        <input
          type="text"
          name="lname"
          value={state.rows[idx].name}
          onChange={handleChange(idx)}
        />
      );
    } else if (ddlSelectedid[idx] === "RADIO") {
      return (
        <input
          type="radio"
          name="lname"
          value={state.rows[idx].name}
          onChange={handleChange(idx)}
        />
      );
    } else if (ddlSelectedid[idx] === "CHECKBOX") {
      return (
        <input
          type="checkbox"
          name="lname"
          value={state.rows[idx].name}
          onChange={handleChange(idx)}
        />
      );
    }
  };

  return (
    <div className="App">
      <table>
        <thead>
          <tr>
            <th>#</th>
            <th>INPUT FNAME</th>
            <th>Dropdown</th>
            <th>INPUT LNAME</th>
            <th>Button</th>
          </tr>
        </thead>
        <tbody>
          {state.rows.map((item, idx) => (
            <tr id="addr0" key={idx}>
              <td>{idx}</td>
              <td>
                <input
                  type="text"
                  name="fname"
                  value={state.rows[idx].name}
                  onChange={handleChange(idx)}
                />
              </td>
              <td>
                <select
                  name="cars"
                  id="cars"
                  onChange={e => handleSelect(e, idx)}
                >
                  <option defaultValue="INPUT">INPUT</option>
                  <option value="RADIO">RADIO</option>
                  <option value="CHECKBOX">CHECKBOX</option>
                </select>
              </td>
              <td>
                {show[idx] && (
                  <input
                    type="text"
                    name="lname"
                    value={state.rows[idx].name}
                    onChange={handleChange(idx)}
                  />
                )}

                {!show[idx] && selectionContent(idx)}
              </td>
              <td>
                <button className="btn" onClick={handleRemoveSpecificRow(idx)}>
                  Remove
                </button>
              </td>
            </tr>
          ))}
        </tbody>
      </table>
      <button onClick={handleAddRow} className="btn">
        Add Row
      </button>
    </div>
  );
}
© www.soinside.com 2019 - 2024. All rights reserved.