繁体   English   中英

在 React 中每两秒更改一次占位符文本

[英]Change placeholder text every two seconds in React

我正在尝试每two更改一次设置的 state 值,并且可以循环运行,但这似乎不适用于以下逻辑。

摘自我的代码

 const placeholderText = ["one", "two", "three"];
  const [state, setState] = useState("");

  useEffect(() => {
    placeholderText.map((val, index) =>
      setTimeout(() => {
        setState(placeholderText[index]);
      }, 2000)
    );
  }, []);

  console.log(state);

当我尝试控制台记录state时,两秒后我一次得到三个值。 如何每两秒设置一次 state 并循环运行以使其不断变化?

我使用CodeSandbox创建了一个工作示例。 有人可以帮忙吗?

您可以使用setInterval而不是setTimeout

此外,我们可以通过这样一种方式简化实现,我们不必将实际文本存储在 state 中,而是可以存储索引。 并在规定的时间间隔后更新。

 const {useState, useEffect} = React; const placeholderText = ["one", "two", "three"]; const Test = () => { const [index, setIndex] = useState(0); useEffect(() => { const timer = () => { setIndex(prevIndex => { if(prevIndex === placeholderText.length - 1){ return 0; } return prevIndex + 1; }) }; setInterval(timer, 2000); //cleanup function in order clear the interval timer //when the component unmounts return () => { clearInterval(timer); } }, []); return <p>{placeholderText[index]}</p> } ReactDOM.render(<Test />, document.getElementById("react"));
 <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> <div id="react"></div>

在这里,为了简单起见,我在组件外部使用了placeholderText 这可以作为 prop 传递给组件并在组件中使用,如下所示,并使用与useEffect挂钩的相同依赖项。

ReactDOM.render(<Test text={placeholderText}/>, document.getElementById("react"));

您正在同时安排它们,因此它们会在 2 秒后同时出现。 我会这样做:

import React, { useState, useEffect } from "react";
import "./styles.css";

const delayExecution = (mls) => {
  return new Promise((resolve) => {
    setTimeout(() => resolve("ok"), mls);
  });
};

export default function App() {
  const placeholderText = ["one", "two", "three"];
  const [state, setState] = useState("");

  const changePlaceholder = async () => {
    for (let i = 0; i < placeholderText.length; i++) {
      await delayExecution(2000);
      setState(placeholderText[i]);
    }
  };

  useEffect(() => {
    changePlaceholder();
  }, []);

  return (
    <div className="App">
      <input type="text" placeholder={state} />
    </div>
  );
}

delayExecution在设定的毫秒数后解析 promise,因此可以等待。 异步 function changePlaceholder执行 rest。

沙盒: https://codesandbox.io/s/priceless-worker-4v4yc?file=/src/App.js

您可以使用 setInterval 而不是 setTimeout 每 2 秒更新一次文本。 像这样的东西:

export default function App() {
  const placeholderText = ["one", "two", "three"];
  const [state, setState] = useState(0);

  useEffect(() => {
    setInterval(() => {
      setState((s) => (s + 1));
    }, 2000);
  }, []);

  const placeholder = placeholderText[state % placeholderText.length]
  return (
    <div className="App">
      <h1>Hello CodeSandbox {placeholder}</h1>
      <h2>Start editing to see some magic happen!</h2>
    </div>
  );
}

它的发生是因为关闭。 如果你想在每 2 秒内更换一次。 您需要setInterval而不是setTimeout 解决此问题的一种方法是使用 IIFE function 以便它使用setInterval中的每个循环值而不是循环最后一个值。 这是代码:

import React, { useState, useEffect } from "react";
import "./styles.css";

export default function App() {
  const placeholderText = ["one", "two", "three"];
  const [state, setState] = useState(0);

  useEffect(() => {
    let interval;

    interval = setInterval(() => {
      setState(function (prev) {
        if (prev === 2) {
          setState(0);
        } else {
          setState(prev + 1);
        }
      });
    }, 2000);

    return () => {
      interval && clearInterval(interval);
    };
  }, []);

  console.log(placeholderText, state);
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      {placeholderText[state]}
    </div>
  );
}

这是演示: https://codesandbox.io/s/magical-swirles-83d8m?file=/src/App.js:0-718

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM