UseState 不保存用户输入
UseState not saving user input
我正在使用 useState 处理待办事项应用程序,我正在尝试保存用户输入,然后在他们单击提交后将其推送到 listArray,稍后显示它...
我认为我在 updateArray 函数中做错了什么,但我似乎能理解是什么。
import React, { useState } from "react";
function App() {
const listArray = [""];
const [list, updateList] = useState("");
function handleChange(event) {
const { name, value } = event.target;
updateList(value);
//console.log(list);
}
function updateArray() {
console.log(list);
listArray.push(list);
console.log(listArray);
}
return (
<div className="container">
<div className="heading">
<h1>To-Do List</h1>
</div>
<div className="form">
<input name="entry" onChange={handleChange} type="text" />
<button>
<span onSubmit={updateArray}>Add</span>
</button>
</div>
<div>
<ul>
<li>{listArray[0]}</li>
</ul>
</div>
</div>
);
}
export default App;
listArray
会在每次重新渲染时被清除。
您应该将数据存储在状态中。所以
const [listArray, setListArray] = useState([])
而 updateArray
应如下所示:
function updateArray() {
setListArray([...listArray, list]);
}
我猜,在updateArray
函数中应该有一些逻辑可以清除list
请注意,当您的应用程序组件 re-renders(使用 useState 可能 re-render 组件)
时,listArray 如何始终返回默认值
我会改为让用户输入的字符串成为一个普通的 const,并为数组使用 useState,这样数组中的值将保存在 re-renders
中
将当前值保存到状态中,并将列表也保存到状态中,这样它就不会在每个渲染周期中被清除。
import React, { useState } from "react";
function App() {
const [list, updateList] = useState([]);
const [currentValue, setCurrentValue] = useState()
function handleChange(event) {
setCurrentValue(event.target.value)
}
function handleClick() {
updateList([...list, currentValue])
}
return (
<div className="container">
<div className="heading">
<h1>To-Do List</h1>
</div>
<div className="form">
<input name="entry" onChange={handleChange} type="text" />
<button type="button" onClick={handleClick}>
<span>Add</span>
</button>
</div>
<div>
<ul>
{list.map((res) => (
<li key={res}>{res}</li>
))}
</ul>
</div>
</div>
);
}
export default App;
此外,将 onClick
移动到按钮在语义上更有意义(甚至对于用户体验而言),但这取决于您。
您当前的代码存在几个问题,我将简要描述并提供解决这些问题的解决方案。
- 您的函数运行良好并且符合预期,但在 React 应用程序中,re-render 页面或组件的方法很少,更改局部变量不是其中之一。所以你需要使用本地状态而不是本地
listArray
变量。由于已经有一个状态,您应该定义另一个状态或使当前状态成为一个对象,并将与组件相关的状态放在一个地方,我将采用第二种方法,因为它更优雅、更简洁。
const [state, setState] = useState({ list: [], input: "" });
- 定义状态后,您需要适当地更改它们而不影响不必要的状态。您只需要发送以前的状态,将其保存在新的状态中,并且只需要更改每个函数中的相关状态即可。因此,使用 ES6 语法,更新
input
状态将如下所示:
setState((prev) => ({ ...prev, input: value })); // immediate return "({})" of an object with iterating through the previous values "...prev" and updating input "input: value"
注意: 您可以阅读更多关于传播运算符 (...
) here.
因此您的 handle
和 updateArray
函数将如下所示:
function handleChange(event) {
const { value } = event.target;
setState((prev) => ({ ...prev, input: value }));
}
function updateArray() {
setState((prev) => ({ ...prev, list: [...state.list, state.input] }));
}
onSubmit
事件仅对表单或提交按钮有效,因此您需要将其更改为 onClick
。此外,要使整个按钮捕捉到 onclick
操作,您需要在按钮本身而不是 span
元素上设置它。
<button onClick={updateArray}> <!-- It's better to assign onclick action to an element with a function or arrow function to prevent it from running in the first render "(event) => updateArray(event)" -->
<span>Add</span>
</button>
- 最后,您需要在 JSX 中映射更新的待办事项数组。
<ul>
{state.list.map((item, index) => (
<li key={index}>{item}</li>
))}
</ul>
工作演示:
我正在使用 useState 处理待办事项应用程序,我正在尝试保存用户输入,然后在他们单击提交后将其推送到 listArray,稍后显示它... 我认为我在 updateArray 函数中做错了什么,但我似乎能理解是什么。
import React, { useState } from "react";
function App() {
const listArray = [""];
const [list, updateList] = useState("");
function handleChange(event) {
const { name, value } = event.target;
updateList(value);
//console.log(list);
}
function updateArray() {
console.log(list);
listArray.push(list);
console.log(listArray);
}
return (
<div className="container">
<div className="heading">
<h1>To-Do List</h1>
</div>
<div className="form">
<input name="entry" onChange={handleChange} type="text" />
<button>
<span onSubmit={updateArray}>Add</span>
</button>
</div>
<div>
<ul>
<li>{listArray[0]}</li>
</ul>
</div>
</div>
);
}
export default App;
listArray
会在每次重新渲染时被清除。
您应该将数据存储在状态中。所以
const [listArray, setListArray] = useState([])
而 updateArray
应如下所示:
function updateArray() {
setListArray([...listArray, list]);
}
我猜,在updateArray
函数中应该有一些逻辑可以清除list
请注意,当您的应用程序组件 re-renders(使用 useState 可能 re-render 组件)
时,listArray 如何始终返回默认值我会改为让用户输入的字符串成为一个普通的 const,并为数组使用 useState,这样数组中的值将保存在 re-renders
中将当前值保存到状态中,并将列表也保存到状态中,这样它就不会在每个渲染周期中被清除。
import React, { useState } from "react";
function App() {
const [list, updateList] = useState([]);
const [currentValue, setCurrentValue] = useState()
function handleChange(event) {
setCurrentValue(event.target.value)
}
function handleClick() {
updateList([...list, currentValue])
}
return (
<div className="container">
<div className="heading">
<h1>To-Do List</h1>
</div>
<div className="form">
<input name="entry" onChange={handleChange} type="text" />
<button type="button" onClick={handleClick}>
<span>Add</span>
</button>
</div>
<div>
<ul>
{list.map((res) => (
<li key={res}>{res}</li>
))}
</ul>
</div>
</div>
);
}
export default App;
此外,将 onClick
移动到按钮在语义上更有意义(甚至对于用户体验而言),但这取决于您。
您当前的代码存在几个问题,我将简要描述并提供解决这些问题的解决方案。
- 您的函数运行良好并且符合预期,但在 React 应用程序中,re-render 页面或组件的方法很少,更改局部变量不是其中之一。所以你需要使用本地状态而不是本地
listArray
变量。由于已经有一个状态,您应该定义另一个状态或使当前状态成为一个对象,并将与组件相关的状态放在一个地方,我将采用第二种方法,因为它更优雅、更简洁。
const [state, setState] = useState({ list: [], input: "" });
- 定义状态后,您需要适当地更改它们而不影响不必要的状态。您只需要发送以前的状态,将其保存在新的状态中,并且只需要更改每个函数中的相关状态即可。因此,使用 ES6 语法,更新
input
状态将如下所示:
setState((prev) => ({ ...prev, input: value })); // immediate return "({})" of an object with iterating through the previous values "...prev" and updating input "input: value"
注意: 您可以阅读更多关于传播运算符 (...
) here.
因此您的 handle
和 updateArray
函数将如下所示:
function handleChange(event) {
const { value } = event.target;
setState((prev) => ({ ...prev, input: value }));
}
function updateArray() {
setState((prev) => ({ ...prev, list: [...state.list, state.input] }));
}
onSubmit
事件仅对表单或提交按钮有效,因此您需要将其更改为onClick
。此外,要使整个按钮捕捉到onclick
操作,您需要在按钮本身而不是span
元素上设置它。
<button onClick={updateArray}> <!-- It's better to assign onclick action to an element with a function or arrow function to prevent it from running in the first render "(event) => updateArray(event)" -->
<span>Add</span>
</button>
- 最后,您需要在 JSX 中映射更新的待办事项数组。
<ul>
{state.list.map((item, index) => (
<li key={index}>{item}</li>
))}
</ul>
工作演示: