setState() 反应后无法按 ctrl Z

发布于 2025-01-15 16:22:23 字数 1710 浏览 0 评论 0原文

我在 中有一个文本通过使用 useState() 获得值“first”。

const [text, setText] = React.useState("");

const setStateOnClick = () => {
  setText("second");
};

const onchangeText = (e) => {
  const value = e.target.value;
  setText(value);
};

return (
  <div>
    <input value={text} onChange={(e) => onchangeText(e)} />
    <button onClick={setStateOnClick}>set new state</button>
  </div>
);

开始,在<输入>中是:“第一个”

在我设置文本之后。

我无法“ctrl Z”来取回开始文本的值(“第一个”)。

我尝试通过“onChange()”捕获该值并将其放入堆栈中,但它会保存每个字母,因此性能会降低。

有没有办法保存“ctrl Z”的状态?谢谢。

解决了。

export default function StateTextFields() {
  const [text, setText] = React.useState("");
  const [textArr, setTextArr] = React.useState([]);
  const typingTimeoutRef = React.useRef(null);

  const setStateOnClick = () => {
    setText("second state");
  };
  const setStateUndo = () => {
    if (textArr.length > 0) {
      const NewArr = [...textArr];
      setText(NewArr[NewArr.length - 1]);
      NewArr.pop();
      setTextArr(NewArr);
    }
  };
  const onchangeText = (e) => {
    const value = e.target.value;
    setText(value);
    if (typingTimeoutRef.current) {
      clearTimeout(typingTimeoutRef.current);
    }
    typingTimeoutRef.current = setTimeout(() => {
      const NewArr = [...textArr];
      NewArr.push(value);
      setTextArr(NewArr);
    }, 300);
  };
  return (
    <div>
      <input value={text} onChange={(e) => onchangeText(e)} />
      <button onClick={setStateOnClick}>second</button>
      <button onClick={setStateUndo}>Undo</button>
    </div>
  );
}

I have a text in <input> have value "first" by using useState().

const [text, setText] = React.useState("");

const setStateOnClick = () => {
  setText("second");
};

const onchangeText = (e) => {
  const value = e.target.value;
  setText(value);
};

return (
  <div>
    <input value={text} onChange={(e) => onchangeText(e)} />
    <button onClick={setStateOnClick}>set new state</button>
  </div>
);

Begin, in <input> is: "first"

After I setText.

I can't "ctrl Z" to take back value("first") of begin text.

I try to catch the value by "onChange()" and put it in a stack, but it save every letters so performance will be decreased.

Is there a way to save the state of "ctrl Z" ? Thank you.

SOVLED.

export default function StateTextFields() {
  const [text, setText] = React.useState("");
  const [textArr, setTextArr] = React.useState([]);
  const typingTimeoutRef = React.useRef(null);

  const setStateOnClick = () => {
    setText("second state");
  };
  const setStateUndo = () => {
    if (textArr.length > 0) {
      const NewArr = [...textArr];
      setText(NewArr[NewArr.length - 1]);
      NewArr.pop();
      setTextArr(NewArr);
    }
  };
  const onchangeText = (e) => {
    const value = e.target.value;
    setText(value);
    if (typingTimeoutRef.current) {
      clearTimeout(typingTimeoutRef.current);
    }
    typingTimeoutRef.current = setTimeout(() => {
      const NewArr = [...textArr];
      NewArr.push(value);
      setTextArr(NewArr);
    }, 300);
  };
  return (
    <div>
      <input value={text} onChange={(e) => onchangeText(e)} />
      <button onClick={setStateOnClick}>second</button>
      <button onClick={setStateUndo}>Undo</button>
    </div>
  );
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

著墨染雨君画夕 2025-01-22 16:22:24

下面提供的是一个工作示例,它显示 Ctrl+Z 可用于撤消输入中键入的文本(除非单击按钮)。

代码片段

const {useState} = React;
const Thingy = () => {
  const [text, setText] = useState("");

  const setStateOnClick = () => {
    setText("second");
  };

  const onchangeText = (e) => {
    const value = e.target.value;
    setText(value);
  };

  return (
    <div>
      <input value={text} onChange={(e) => onchangeText(e)} />
      <br/>
      <br/>
      value in real-time: {text} <br/>
      Can use Ctrl+Z to undo entered text
      <br/>
      <br/>
      <button onClick={setStateOnClick}>set new state</button>
      <br />
      Cannot Ctrl+Z after above button is clicked !
    </div>
  );
};

ReactDOM.render(
  <div>
    <Thingy />
  </div>,
  document.getElementById("rd")
);
<div id="rd" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script>

编辑

根据更新的问题,添加了一个新按钮“撤消”。

  • 当用户单击第一个按钮(“确认文本”)时,将保存用户输入的原始文本。
  • 此信息也存储在数组 pastItems 中。
  • pastItems中有条目时,“撤消”按钮将启用,并允许用户逐一调用值,直到没有值为止。
const {useState} = React;
const Thingy = () => {
  const [text, setText] = useState("");
  const [pastItems, setPastItems] = useState([]);

  const setStateOnClick = () => {
    setPastItems(prev => ([...prev, text]));
    setText('');
    // setText(prev => (`${prev} - set to state`));
  };
  
  const undoOnClick = () => {
    const prevText = pastItems.pop();
    setPastItems([...pastItems]);
    setText(prevText);
  };

  const onchangeText = (e) => {
    const value = e.target.value;
    setText(value);
  };

  return (
    <div>
      <label for="userInput">Type some text here:  </label>
      <input id="userInput" value={text} onChange={(e) => onchangeText(e)} />
      <br/>
      <br/>
      value in real-time: {text} <br/>
      prev values in real-time: {pastItems.join(', ')} <br/>
      Can use Ctrl+Z to undo entered text
      <br/>
      <br/>
      <button onClick={setStateOnClick}>Confirm text</button>
         
      <button onClick={undoOnClick} disabled={pastItems.length === 0}>Undo</button>
      <br /><br />
      Can "Undo" after 'Confirm' button is clicked !
    </div>
  );
};

ReactDOM.render(
  <div>
    <Thingy />
  </div>,
  document.getElementById("rd")
);
<div id="rd" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script>

Provided below is a working-example which shows that Ctrl+Z may be used to undo text typed in the input (unless the button is clicked).

Code Snippet

const {useState} = React;
const Thingy = () => {
  const [text, setText] = useState("");

  const setStateOnClick = () => {
    setText("second");
  };

  const onchangeText = (e) => {
    const value = e.target.value;
    setText(value);
  };

  return (
    <div>
      <input value={text} onChange={(e) => onchangeText(e)} />
      <br/>
      <br/>
      value in real-time: {text} <br/>
      Can use Ctrl+Z to undo entered text
      <br/>
      <br/>
      <button onClick={setStateOnClick}>set new state</button>
      <br />
      Cannot Ctrl+Z after above button is clicked !
    </div>
  );
};

ReactDOM.render(
  <div>
    <Thingy />
  </div>,
  document.getElementById("rd")
);
<div id="rd" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script>

EDIT

Based on updated question, a new button "Undo" has been added.

  • The original text typed by the user is saved when user clicks the first button ("Confirm text").
  • This info is also stored on an array pastItems.
  • When there are entries in pastItems the "Undo" button is enabled and allows user to recall values one-by-one till no values remain.

const {useState} = React;
const Thingy = () => {
  const [text, setText] = useState("");
  const [pastItems, setPastItems] = useState([]);

  const setStateOnClick = () => {
    setPastItems(prev => ([...prev, text]));
    setText('');
    // setText(prev => (`${prev} - set to state`));
  };
  
  const undoOnClick = () => {
    const prevText = pastItems.pop();
    setPastItems([...pastItems]);
    setText(prevText);
  };

  const onchangeText = (e) => {
    const value = e.target.value;
    setText(value);
  };

  return (
    <div>
      <label for="userInput">Type some text here:  </label>
      <input id="userInput" value={text} onChange={(e) => onchangeText(e)} />
      <br/>
      <br/>
      value in real-time: {text} <br/>
      prev values in real-time: {pastItems.join(', ')} <br/>
      Can use Ctrl+Z to undo entered text
      <br/>
      <br/>
      <button onClick={setStateOnClick}>Confirm text</button>
         
      <button onClick={undoOnClick} disabled={pastItems.length === 0}>Undo</button>
      <br /><br />
      Can "Undo" after 'Confirm' button is clicked !
    </div>
  );
};

ReactDOM.render(
  <div>
    <Thingy />
  </div>,
  document.getElementById("rd")
);
<div id="rd" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script>

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文