简体   繁体   English

如何处理 React.js 中未知数量的 state 个变量?

[英]How to handle unknown number of state variables in React.js?

I am getting data from server.我正在从服务器获取数据。 I don't know exactly how many items in the api. Therefore, I am using map method in html. Below is the return part.我不知道api到底有多少项,所以我在html中使用了map的方法,下面是返回部分。

   if (loading) {
    return (
      <div>
        <div>
          <Header />
          <Sidebar />
        </div>
        <h1>LOADING ...</h1>
      </div>
    );
  }
  if (error) console.log(error);
  return (
    <div>
      <div>
        <Header />
        <Sidebar />
        <h1>Menu Edit Page</h1>
        {edit === false ? (
          <div>
            <table>
              <tbody>
            {
              data?.map((item, index) => (
                <tr>
                  <td>Name: </td>
                  <td>{item?.name}</td>
                  {/* Full_Name: { item.name }, 
                User_Email: { item.email }  */}
                </tr>
              ))
            }
            </tbody>
            </table>
            <Button onClick={() => editMenu()}>edit</Button>
          </div>
        ) : (
          <div>
            <table>
              <tbody>
            {
              data?.map((item, index) => (
                <tr>
                  <td>Name: </td>
                  <input
                  type="text"
                  required="required"
                  placeholder="Edit menu item"
                  name="age"
                  defaultValue={item?.name}
                  onChange={() => itemChange(item?.class, item?.id)}
                  >
                  </input>
                  {/* {item?.name} */}
                  {/* Full_Name: { item.name }, 
                User_Email: { item.email }  */}
                </tr>
              ))
            }
            </tbody>
            </table>
            <Button onClick={() => saveMenu()}>save</Button>
          </div>
        )}
      </div>
    </div>
  )

When i use input tag for objects, I need to manipulate them when i click the button.当我为对象使用输入标签时,我需要在单击按钮时操作它们。 However, I dont know how many objects, so I cannot use state variables.但是,我不知道有多少个对象,所以我不能使用 state 个变量。 Moreover, i need to know information from object itself when i change the object. Whole code is below.此外,当我更改 object 时,我需要从 object 本身了解信息。整个代码如下。

 import React, { useState } from 'react'
import Header from "../Components/common/header/header";
import Sidebar from "../Components/common/sidebar/Sidebar";/// IGNORE THIS PAGE
import useFetch from './useFetch';
import { Button } from 'antd';
function MenuEditer() {
  const [newItem, setNewItem] = useState("")
  const [edit, setEdit] = useState(false);
  const [buttonPressed, setButtonPressed] = useState(false);
  const { data, loading, error } = useFetch("http://localhost:3001/category/deneme");

  const itemChange = async (clss, id) => {
    alert("beginning of the func");
    // while(!buttonPressed);
    // alert("button pressed");
    // if(clss === "category"){

    // }
    // if(clss === "item"){

    // }
  }
  const saveMenu = async () => {
    setButtonPressed(true);
    setEdit(false);
  }
  const editMenu = async () => {
    setEdit(true);
  }
  if (loading) {
    return (
      <div>
        <div>
          <Header />
          <Sidebar />
        </div>
        <h1>LOADING ...</h1>
      </div>
    );
  }
  if (error) console.log(error);
  return (
    <div>
      <div>
        <Header />
        <Sidebar />
        <h1>Menu Edit Page</h1>
        {edit === false ? (
          <div>
            <table>
              <tbody>
            {
              data?.map((item, index) => (
                <tr>
                  <td>Name: </td>
                  <td>{item?.name}</td>
                  {/* Full_Name: { item.name }, 
                User_Email: { item.email }  */}
                </tr>
              ))
            }
            </tbody>
            </table>
            <Button onClick={() => editMenu()}>edit</Button>
          </div>
        ) : (
          <div>
            <table>
              <tbody>
            {
              data?.map((item, index) => (
                <tr>
                  <td>Name: </td>
                  <input
                  type="text"
                  required="required"
                  placeholder="Edit menu item"
                  name="age"
                  defaultValue={item?.name}
                  onChange={() => itemChange(item?.class, item?.id)}
                  >
                  </input>
                  {/* {item?.name} */}
                  {/* Full_Name: { item.name }, 
                User_Email: { item.email }  */}
                </tr>
              ))
            }
            </tbody>
            </table>
            <Button onClick={() => saveMenu()}>save</Button>
          </div>
        )}
      </div>
    </div>
  )
}

export default MenuEditer;

How can I reach object itself from the array, or use useState hook without knowing the length of data?如何从数组中到达 object 本身,或者在不知道数据长度的情况下使用 useState hook? OR, can i write statements of function in onClick attribute?或者,我可以在 onClick 属性中写 function 的语句吗? OR, can i use anything else for input form for specifically reach the object and updated string?或者,我可以使用其他任何输入表单来专门到达 object 和更新的字符串吗? The issue may not be clear but I would be very appreciated to any idea.这个问题可能不清楚,但我将不胜感激任何想法。 Thanks!谢谢!

you can use an object to handle the inputs data您可以使用 object 来处理输入数据

at first use useEffect to set the initial values of the state首先使用useEffect设置 state 的初始值

Note make sure that the property name for the HTML input is the same as the one that comes form the API the请注意,确保 HTML 输入的属性name与来自 API 的属性名称相同

const [formData, setFormData] = useState({})

useEffect(() => {
  const copy = formData
  data.forEach((item,index)=> {
   copy["item" + index] = {name: item.name, email: item.email}

    setFormData(copy)
})
}, [])

then allow the event handler to automatically handle the change然后允许事件处理程序自动处理更改

const itemChange = (event, index) {
  const copy = formData
  const changedItem = copy["item" + index]
  changedItem[event.target.name] = event.target.value

 setFormData(copy)
  
}

in the input element在输入元素中

<input
     type="text"
     required={true}
     placeholder="Edit menu item"
     name="age"  // make sure the name is same as the property name that comes form the api
     value={formData["item" + index].age}
     onChange={(e) => itemChange(e, index)}
 />

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM