如何使用 useState 在 React Typescript 中推送嵌套对象接口数组
How to push nested object interface array in React Typescript using useState
界面
interface ListInterface {
listName: string;
list: string[];
}
useState
const [initialList, setinitialList] = useState<ListInterface>({listName: "List1", list:['One', 'Two', 'Three', 'Four', 'Five', 'Six']});
const [selectedList, setSelectedList] = useState<ListInterface>(initialList);
我知道如何向数组添加新元素(推送)。但是当数组在 object/inteface 中时会遇到麻烦。你是如何使用 useState 挂钩的?
setTheArray(oldArray => [...oldArray, newElement]);
我创建了一个简单的沙箱示例。
- 使用输入字段向数组添加新文本
selectedList.list
https://codesandbox.io/s/reacr-ts-nested-object-array-example-z1uyd?file=/src/App.tsx
您已经定义了一个对象接口,这意味着您需要在每次更新时推送一个符合该类型的对象。
// ...
const [text, setText] = useState<string>(''); // <--- set type and set to blank to remove type errors due to `text` being possibly undefined
// ...
const handleSubmit = (event: any) => {
event.preventDefault();
console.log("Submitted: " + text);
//setSelectedList({list: oldArray => [...oldArray, newElement]});
// the above wont work because it is an array, but `ListInterface` is an object (you might want to change the name to `ListEntry` or `ListObject` to avoid confusion)
setSelectedList({
listName: selectedList.listName,
list: [...selectedList.list, text]
})
};
感谢接受。也请查看@axtck 的回答,因为他们对您的代码进行了其他一些重要改进!
您不应该为您的初始对象初始化状态变量,您可以只使用接口并以这种方式声明它:
const initialList: ListInterface = {
listName: "List1",
list: ["One", "Two", "Three", "Four", "Five", "Six"]
};
因为你只想更新对象内部的列表,你可以这样使用functional setState()
:
const handleSubmit = (event: any) => {
console.log("Submitted: " + text);
event.preventDefault();
setSelectedList((prevState) => {
return { ...prevState, list: prevState.list = [...prevState.list, text] };
});
};
当 mapping
时,请确保您传递了有效的 key
:
{selectedList.list.map((item, i) => {
return <h3 key={i}>{item}</h3>;
})}
完整代码并已更新 sandbox:
import { useState } from "react";
import "./styles.css";
export default function App() {
interface ListInterface {
listName: string;
list: string[];
}
const initialList: ListInterface = {
listName: "List1",
list: ["One", "Two", "Three", "Four", "Five", "Six"]
};
const [selectedList, setSelectedList] = useState<ListInterface>(initialList);
const [text, setText] = useState("");
const handleChange = (event: any) => {
setText(event.target.value);
};
const handleSubmit = (event: any) => {
console.log("Submitted: " + text);
event.preventDefault();
setSelectedList((prevState) => {
return { ...prevState, list: prevState.list = [...prevState.list, text] };
});
};
return (
<div className="App">
{selectedList.list.map((item, i) => {
return <h3 key={i}>{item}</h3>;
})}
<form onSubmit={handleSubmit}>
<label>
Add To List:
<input type="text" value={text} onChange={handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
</div>
);
}
界面
interface ListInterface {
listName: string;
list: string[];
}
useState
const [initialList, setinitialList] = useState<ListInterface>({listName: "List1", list:['One', 'Two', 'Three', 'Four', 'Five', 'Six']});
const [selectedList, setSelectedList] = useState<ListInterface>(initialList);
我知道如何向数组添加新元素(推送)。但是当数组在 object/inteface 中时会遇到麻烦。你是如何使用 useState 挂钩的?
setTheArray(oldArray => [...oldArray, newElement]);
我创建了一个简单的沙箱示例。
- 使用输入字段向数组添加新文本
selectedList.list
https://codesandbox.io/s/reacr-ts-nested-object-array-example-z1uyd?file=/src/App.tsx
您已经定义了一个对象接口,这意味着您需要在每次更新时推送一个符合该类型的对象。
// ...
const [text, setText] = useState<string>(''); // <--- set type and set to blank to remove type errors due to `text` being possibly undefined
// ...
const handleSubmit = (event: any) => {
event.preventDefault();
console.log("Submitted: " + text);
//setSelectedList({list: oldArray => [...oldArray, newElement]});
// the above wont work because it is an array, but `ListInterface` is an object (you might want to change the name to `ListEntry` or `ListObject` to avoid confusion)
setSelectedList({
listName: selectedList.listName,
list: [...selectedList.list, text]
})
};
感谢接受。也请查看@axtck 的回答,因为他们对您的代码进行了其他一些重要改进!
您不应该为您的初始对象初始化状态变量,您可以只使用接口并以这种方式声明它:
const initialList: ListInterface = {
listName: "List1",
list: ["One", "Two", "Three", "Four", "Five", "Six"]
};
因为你只想更新对象内部的列表,你可以这样使用functional setState()
:
const handleSubmit = (event: any) => {
console.log("Submitted: " + text);
event.preventDefault();
setSelectedList((prevState) => {
return { ...prevState, list: prevState.list = [...prevState.list, text] };
});
};
当 mapping
时,请确保您传递了有效的 key
:
{selectedList.list.map((item, i) => {
return <h3 key={i}>{item}</h3>;
})}
完整代码并已更新 sandbox:
import { useState } from "react";
import "./styles.css";
export default function App() {
interface ListInterface {
listName: string;
list: string[];
}
const initialList: ListInterface = {
listName: "List1",
list: ["One", "Two", "Three", "Four", "Five", "Six"]
};
const [selectedList, setSelectedList] = useState<ListInterface>(initialList);
const [text, setText] = useState("");
const handleChange = (event: any) => {
setText(event.target.value);
};
const handleSubmit = (event: any) => {
console.log("Submitted: " + text);
event.preventDefault();
setSelectedList((prevState) => {
return { ...prevState, list: prevState.list = [...prevState.list, text] };
});
};
return (
<div className="App">
{selectedList.list.map((item, i) => {
return <h3 key={i}>{item}</h3>;
})}
<form onSubmit={handleSubmit}>
<label>
Add To List:
<input type="text" value={text} onChange={handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
</div>
);
}