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 移动到按钮在语义上更有意义(甚至对于用户体验而言),但这取决于您。

您当前的代码存在几个问题,我将简要描述并提供解决这些问题的解决方案。

  1. 您的函数运行良好并且符合预期,但在 React 应用程序中,re-render 页面或组件的方法很少,更改局部变量不是其中之一。所以你需要使用本地状态而不是本地 listArray 变量。由于已经有一个状态,您应该定义另一个状态或使当前状态成为一个对象,并将与组件相关的状态放在一个地方,我将采用第二种方法,因为它更优雅、更简洁。
const [state, setState] = useState({ list: [], input: "" });
  1. 定义状态后,您需要适当地更改它们而不影响不必要的状态。您只需要发送以前的状态,将其保存在新的状态中,并且只需要更改每个函数中的相关状态即可。因此,使用 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.

因此您的 handleupdateArray 函数将如下所示:

function handleChange(event) {
  const { value } = event.target;
  setState((prev) => ({ ...prev, input: value }));
}

function updateArray() {
  setState((prev) => ({ ...prev, list: [...state.list, state.input] }));
}
  1. 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>
  1. 最后,您需要在 JSX 中映射更新的待办事项数组。
<ul>
  {state.list.map((item, index) => (
      <li key={index}>{item}</li>
  ))}
</ul>

工作演示: