列表中的 React Hooks 输入

React Hooks Inputs inside the List

美好的一天,

我正在尝试使用反应钩子在列表中创建一个表单。到目前为止,我很挣扎,因为我只熟悉如何在单个状态下进行状态更改。

import React from "react"

export function TestApp () {
    const [input, setInput] = useState("");

    function submitData(){
    // TODO
    }

    return (
        <>
            <input onChange={e=>setInput(e.target.value)} value={value} />
            <button type="button" onClick={submitData}>Submit</button>
        </>
    )
}

我的示例场景是这样的:有一个来自 Web api 的数据列表,我需要在列表中进行迭代。在该列表中,有一个输入,用户可以在其中键入或更新数据。像下面这样的东西,但它不能正常工作。

import React from "react"

export function TestApp () {
    const [customers, setCustomers] = useState([])
    useEffect(()=>{
         axios.get(`api/customers`).then(response => {
            setCustomers(response.data)
            // suppose the result will be something like:
            // [{id:1, name: "James", {id: 2, name: "Josh"}]
         ).catch(error=>console.log(error));
    }, [])

    const [inputs, setInputs] = useState([]);

    function submitData(){
    // TODO
        console.log(inputs)
        // something like the result will be if the user just added "updated" after the name inside the input list 
        [{id:1, name: "James updated", {id: 2, name: "Josh updated"}]
    }

    function handleOnChange(e, data){
        setInputs(...inputs, {
            id: data.id, 
            name: data.name
        })
    }

    return (
        <> 
           {customers.map((data)=> (
                <input onChange={e=>handleOnChange(e, data)} value={data.name} />
           ))};
            <button type="button" onClick={submitData}>Submit</button>
        </>
    )
}

我想要做的是,当用户在所选行内键入时,它会在数组内发生变异 changes/updates。因为 inputs 中的数据是我可以用来在后端制作 changes/updates 的地方。

谢谢你,我希望有人能帮助我。

映射时,获取正在迭代的项目的当前索引并将其传递给函数。在函数中,对该索引前后的数组进行切片,并在索引本身处替换 name 属性:

const changeName = (i, newName) => {
  setCustomers([
    ...customers.slice(0, i),
    { ...customers[i], name: newName },
    ...customers.slice(i + 1)
  ]);
};
// ...
 {customers.map((item, i)=> (
      <input onChange={e => changeName(i, e.currentTarget.value)} value={item.name} />
 ))};
// ...