【问题标题】:Text field should only change for one value and not over the entire list文本字段应仅更改一个值,而不应更改整个列表
【发布时间】:2021-10-29 07:49:58
【问题描述】:

我有一个列表,这个列表有几个元素,我遍历列表。对于每个列表,我显示两个按钮和一个输入字段。

现在我遇到了以下问题:我在文本字段中写入内容后,其他文本字段中也会输入相同的值。但是,我只想更改一个文本字段中的值,因此其他文本字段不应接收此值。

我怎样才能使一个文本字段用于一个元素,而当我在该文本字段中写入内容时,它不适用于所有其他元素?

从 'react' 导入 React, { useState, useEffect } 从'axios'导入axios

function Training({ teamid }) {


    const [isTrainingExisting, setIsTrainingExisting] = useState(false);
    const [trainingData, setTrainingData] = useState([]);

    const [addTraining, setAddTraining] = useState(false);

    const [day, setDay] = useState('');
    const [from, setFrom] = useState('');
    const [until, setUntil] = useState('');


    const getTrainingData = () => {
        axios
            .get(`${process.env.REACT_APP_API_URL}/team/team_training-${teamid}`,
        )
            .then((res) => {
                if (res.status === 200) {
                    if (typeof res.data !== 'undefined' && res.data.length > 0) {
                        // the array is defined and has at least one element
                        setIsTrainingExisting(true)
                        setTrainingData(res.data)
                    }
                    else {
                        setIsTrainingExisting(false)
                    }


                }
            })
            .catch((error) => {
                //console.log(error);

            });

    }

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



    const deleteTraining = (id) => {
        axios
            .delete(`${process.env.REACT_APP_API_URL}/team/delete/team_training-${teamid}`,
                { data: { trainingsid: `${id}` } })
            .then((res) => {
                if (res.status === 200) {
                    var myArray = trainingData.filter(function (obj) {
                        return obj.trainingsid !== id;
                    });
                    //console.log(myArray)
                    setTrainingData(() => [...myArray]);
                }
            })
            .catch((error) => {
                console.log(error);

            });
    }

    const addNewTraining = () => {
        setAddTraining(true);
    }

    const addTrainingNew = () => {
        axios
            .post(`${process.env.REACT_APP_API_URL}/team/add/team_training-${teamid}`,
                { von: `${from}`, bis: `${until}`, tag: `${day}` })
            .then((res) => {
                if (res.status === 200) {
                    setAddTraining(false)
                    const newTraining = {
                        trainingsid: res.data,
                        mannschaftsid: teamid,
                        von: `${from}`,
                        bis: `${until}`,
                        tag: `${day}`
                    }
                    setTrainingData(() => [...trainingData, newTraining]);
                    //console.log(trainingData)
                }
            })
            .catch((error) => {
                console.log(error);

            });
    }

    const [editing, setEditing] = useState(null);

    const editingTraining = (id) => {
        //console.log(id)
        setEditing(id);
    };

    const updateTraining = (trainingsid) => {

    }


    return (
        <div>
            {trainingData.map((d, i) => (
                <div key={i}>
                    Trainingszeiten
                    <input class="input is-normal" type="text"  key={ d.trainingsid } value={day} placeholder="Wochentag" onChange={event => setDay(event.target.value)} readOnly={false}></input>
                        {d.tag} - {d.von} bis {d.bis} Uhr
                        <button className="button is-danger" onClick={() => deleteTraining(d.trainingsid)}>Löschen</button>

                        {editing === d.trainingsid ? (
                            <button className="button is-success" onClick={() => { editingTraining(null); updateTraining(d.trainingsid); }}>Save</button>
                        ) : (
                            <button className="button is-info" onClick={() => editingTraining(d.trainingsid)}>Edit</button>
                        )}


                        <br />
                </div>
            ))}


            )
}

            export default Training

【问题讨论】:

  • &lt;input class="input is-normal" name={i} type="text" value={d.day} placeholder="Day" onChange={event =&gt; setDay(event.target.value)}&gt;&lt;/input&gt; 还是一样 - 为什么是按钮?该按钮可以正常工作,但输入字段与key={i} 不同
  • 对不起。已编辑。应该是输入的。您可以在此处阅读有关如何使用单个函数处理多个输入的更多信息:pluralsight.com/guides/…
  • setDay 在哪里
  • 能否提供完整的组件?有几个缺失的部分让人很难理解。
  • iunfixit 和 Kavindu VIndika 请看看我的编辑

标签: reactjs list input


【解决方案1】:

您看到所有字段都发生变化的原因是,当您使用 .map 构建输入元素时,您可能分配了相同的 onChange 事件并使用相同的状态值来为输入元素提供值。

您应该正确管理这些信息并将元素与其处理程序隔离开来。在useReducer 或您选择的其他范例的帮助下,有几种方法可以有效地管理此问题。我将提供一个简单的示例,显示问题与受控方法没有问题,

这是我怀疑你正在做的,这将显示问题。如您所见,这里我使用val 设置&lt;input/&gt;value,并且对于我们正在为其构建元素的两个项目重复发生这种情况,

const dataSource = [{id: '1', value: 'val1'}, {id: '2', value: 'val2'}]

export default function App() {
  const [val, setVal]= useState('');
  const onTextChange = (event) => {
    setVal(event.target.value);

  }

  return (
    <div className="App">
      {dataSource.map(x => {
        return (
          <div key={x.id}>
           <input type="text" value={val} onChange={onTextChange}/>
          </div>
        )
      })}
    </div>
  );
}

这就是你要做的事情。

export default function App() {
  const [data, setData]= useState(dataSource);

  const onTextChange = (event) => {
    const id = String(event.target.dataset.id);
    const val = String(event.target.value);
    const match = data.find(x => x.id === id);
    const updatedItem = {...match, value: val};
    if(match && val){
      const updatedArrayData = [...data.filter(x => x.id !== id), updatedItem];
      const sortedData = updatedArrayData.sort((a, b) => Number(a.id) - Number(b.id));
      console.log(sortedData);
      setData(sortedData); // sorting to retain order of elements or else they will jump around
    }
  }

  return (
    <div className="App">
      {data.map(x => {
        return (
          <div key={x.id}>
            <input data-id={x.id} type="text" value={x.value} onChange={onTextChange}/>
          </div>
        )
      })}
    </div>
  );
}

我在这里做的是,找到一种方法来在标识符的帮助下将元素映射到它自己的元素。我已经为它使用了data-id 属性。我在回调中再次使用这个值来识别匹配,正确更新它并再次更新状态,以便重新渲染显示正确的值。

【讨论】:

    猜你喜欢
    • 2011-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-11
    • 1970-01-01
    • 1970-01-01
    • 2016-04-19
    • 1970-01-01
    相关资源
    最近更新 更多