javascript - 如何处理多个输入是可编辑的
问题描述
我在反应中为多个输入添加了动态值,然后我尝试对其进行编辑,但它根本不可编辑。这是代码:
class Hotels extends React.Component {
constructor(props) {
super(props);
this.state = {
data: [
{ id: 1, hotel: { name: "Sentido" } },
{ id: 2, hotel: { name: "Maris" } },
{ id: 3, hotel: { name: "Orka" } },
{ id: 4, hotel: { name: "Resort " } },
{ id: 5, hotel: { name: "Green " } },
{ id: 6, hotel: { name: "Maris" } },
{ id: 7, hotel: { name: "Nature " } },
{ id: 8, hotel: { name: "Diamond " } },
],
};
}
render() {
return data.map((item, i) => (
<input
name={`hotel__${i}.name`}
onChange={this.handleChange}
value={item.hotel.name}
type="text"
/>
));
}
handleChange = (event) => {
this.setState({
[event.target.name]: event.target.value,
});
};
}
ReactDOM.render(<Hotels></Hotels>, document.getElementById("app"));
我不使用 defaultValue 属性并添加了一个 onChange 事件,但它不起作用!
解决方案
您的项目有一个id
属性,因此不需要使用数组索引,例如name={`hotel__${i}.name`}
我建议使用item.id
。id只是identifier的缩写,它应该标识一个资源。
有了这个建议,您必须传递一个资源标识符来handleChange
识别要更改的资源。这可以通过多种方式完成。
将标识符或索引或项目id与事件一起传递给
handleChange
.onChange={(event) => this.handleChange(event, item.id)} // ... handleChange = (event, id) => { const name = event.target.value; this.setState((previous) => ({ data: previous.data.map((item) => { if (item.id != id) return item; return { ...item, hotel: { name } }; // add `...item.hotel` ^ if hotel contains more attributes // than just the name }) })); };
这与第一个解决方案有很多共同之处。您可以使用已经提供
handleChange
的id创建一个 curried 版本。onChange={this.handleChange(item.id)} // ... handleChange = (id) => (event) => { // ... };
更新状态的解决方案不止这两种,但这些可能是最容易掌握的。
class Hotels extends React.Component {
constructor(props) {
super(props);
this.state = {
data: [
{ id: 1, hotel: { name: "Sentido" } },
{ id: 2, hotel: { name: "Maris" } },
{ id: 3, hotel: { name: "Orka" } },
{ id: 4, hotel: { name: "Resort " } },
{ id: 5, hotel: { name: "Green " } },
{ id: 6, hotel: { name: "Maris" } },
{ id: 7, hotel: { name: "Nature " } },
{ id: 8, hotel: { name: "Diamond " } },
],
};
}
render() {
return this.state.data.map((item) => (
<input
key={item.id}
name={`hotel__${item.id}.name`}
onChange={this.handleChange(item.id)}
value={item.hotel.name}
type="text"
/>
));
}
handleChange = (id) => (event) => {
const name = event.target.value;
this.setState((previous) => ({
data: previous.data.map((item) => {
if (item.id != id) return item;
return { ...item, hotel: { name } };
// add `...item.hotel` ^ if hotel contains more attributes
// than just the name
})
}));
};
}
ReactDOM.render(<Hotels />, document.getElementById("app"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="app"></div>
上面的代码片段使用name={`hotel__${item.id}.name`}
,但如果您无法更改或更喜欢使用索引,则可以使用原始名称。
推荐阅读
- mysql - SQL计算具有行值的不同列
- flutter - 错误:不能将“String”类型的值分配给“int”类型的变量
- perl - 停止使用 DB::DB 创建的探查器以再次显示未真正调用的调用
- android - Android Compose MVVM 多网络调用
- json - 如何在列表中显示列的所有文本?
- arrays - 我在 malloc 哪里做错了?
- git - 相当于 p4 sync -n 的 git 命令
- c# - 如何使用 Graph Api 替换 Onedrive 中的文件?
- python - 如何干净地使用 QuickSort 对链表进行排序 - Python
- clojure - 是否可以在 deps.edn 中设置 `*warn-on-reflection*?