簡體   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