如何使用 event.target.value 重置状态并使其在多个 <li> 上持续存在

How to reset state with event.target.value and make it persist on multiple <li>

我正在尝试获取按下按键时的用户输入并将其传递给下一个上方的列表。我觉得必须有一种方法可以重置状态并使其持续存在,但我就是想不通?我该如何理解?

import { useState, useEffect, useRef, useMemo } from 'react';
import '../sign.css';

const VALUES = [
  { id: 1, label: "name", text: "Hi, What is your Name?", placeholder: "Enter your full name" },
  { id: 2, label: "uname", text: "What shall we call you?", placeholder: "Enter a username" },
  { id: 3, label: "email", text: "Enter you email", placeholder: "Email" },
  { id: 4, label: "password", text: "Choose a password", placeholder: "make sure you dont forget" },
  { id: 5, label: "signup", text: "sign up", placeholder: ""},
];


export default function SignUp() {
  
  const [show, setShow] = useState(VALUES)
  const [currentIndex, setCurrentIndex] = useState(0);
  const [details, setDetails] = useState('');

  useEffect(() => {
    
  }, [show]);
  
  const onKeyPressed = (ev, id) => {
    if (ev.charCode === 13) {
      ev.preventDefault();
      const nextRender = currentIndex + 1;
      if (nextRender < show.length) {
        setCurrentIndex(nextRender);
        setDetails(ev.target.value);
      } else {
        //todo
      }
    }
  }
  const displayItem = useMemo(() => show[currentIndex], [show, currentIndex]);
 
  return (
    <div className="container" id="container">
      <div className="navigation">
        <ol>
            <li><a href="#"  dataref="name">{this should display their name}</a></li>
            <li><a href="#"  dataref="uname">{this should display their username}</a></li>
            <li><a href="#"  dataref="email">{this should display their email}</a></li>
        </ol>
      </div>
      <form id="sign-form" className="sign-form">
        <ol className="questions">
          {
            <li onKeyPress={(KeyboardEvent) => onKeyPressed(KeyboardEvent, displayItem.id)} key={displayItem.id} >
              <span><label htmlFor={displayItem.label}>{displayItem.text}</label></span>
              <input id={displayItem.id} name={displayItem.label} type="text" placeholder={displayItem.placeholder} autoFocus/>
            </li>
          };  
        </ol>
     </form>
    </div>
  )

我给了你我认为你想要的代码

import { useState, useEffect, useRef, useMemo } from 'react';

const VALUES = [
  { id: 1, label: "name", text: "Hi, What is your Name?", placeholder: "Enter your full name" },
  { id: 2, label: "uname", text: "What shall we call you?", placeholder: "Enter a username" },
  { id: 3, label: "email", text: "Enter you email", placeholder: "Email" },
  { id: 4, label: "password", text: "Choose a password", placeholder: "make sure you dont forget" },
  { id: 5, label: "signup", text: "sign up", placeholder: ""},
];


export default function SignUp() {

  const [show, setShow] = useState(VALUES)
  const [currentIndex, setCurrentIndex] = useState(0);
  const [details, setDetails] = useState({});

  useEffect(() => {

  }, [show]);

  const onKeyPressed = ( ev, id ) => {
    if (ev.charCode === 13) {
      ev.preventDefault();
      const nextRender = currentIndex + 1;
      if (nextRender < show.length) {
        setCurrentIndex(nextRender);
        const label = VALUES[currentIndex].label;
        details[label] = ev.target.value;
        setDetails(details);
      } else {
        //todo
      }
    }
  }
  const displayItem = useMemo(() => show[currentIndex], [show, currentIndex]);

  return (
    <div className="container" id="container">
      <div className="navigation">
        <ol>
          {Object.keys(details).map((key) => (
            <li><a href="#" dataref={key}>{key}: {details[key]}</a></li>
          ))}
        </ol>
      </div>
      <form id="sign-form" className="sign-form">
        <ol className="questions">
          <li onKeyPress={( KeyboardEvent ) => onKeyPressed(KeyboardEvent, displayItem.id)} key={displayItem.id}>
            <span><label htmlFor={displayItem.label}>{displayItem.text}</label></span>
            <input id={displayItem.id} name={displayItem.label} type="text" placeholder={displayItem.placeholder}
                   autoFocus/>
          </li>
        </ol>
      </form>
    </div>
  )
}

好的,我想我现在明白你的意思了。我有 运行 CodeSandbox 中的代码,它很有意义。您想像步进器一样进行注册,一次问一个问题。

在对象中存储值仍然是一种更可取的方式。但是您需要获取值的标签并将其附加到现有对象。当你通过步进器时,你可以用数据构建你的对象。

这是一个可行的解决方案。希望这就是您要找的:https://codesandbox.io/s/unruffled-pasteur-76xux4?file=/src/App.js

我修改了 onKeyPressed 以根据我们当前所在的索引从 VALUES 数组中获取标签。然后该标签用作对象内部的键,其中值是来自事件处理程序的值

 const onKeyPressed = (ev, id) => {
    if (ev.charCode === 13) {
      ev.preventDefault();
      const label = show[currentIndex].label; // grab the label based on the current index
      const nextRender = currentIndex + 1;
      if (nextRender < show.length) {
        setCurrentIndex(nextRender);
        setDetails({ ...details, [label]: ev.target.value }); // add the value to the details object where key is the label
      } else {
        //todo
      }
    }
  };