在setInterval()内部时,值未更新

时间:2020-04-04 17:46:27

标签: reactjs

const [value, setValue] = useState<string | undefined>("");

  useEffect(() => {
    let i = 0;
    const valueInterval = setInterval(() => {
      setValue(oldValue => {
        if (oldValue === INTRO_TEXT) {
          clearInterval(valueInterval);
          return value;
        }
        console.warn(oldValue)
        return oldValue ? oldValue + INTRO_TEXT.charAt(i) + "" : "";
      });
      i++;
    }, 100);

    return () => {
      clearInterval(valueInterval);
    };
  }, [value]);

我想一个接一个地添加一个字符,直到得到等于INTRO_TEXT的字符,但是oldValue似乎总是undefined,即,它不像我一样更新状态想要。 setInterval中我在做什么错?

2 个答案:

答案 0 :(得分:4)

  1. 您已将value作为依赖项添加到useEffect,因此将状态设置为将重新渲染组件并重置整个组件。
  2. “”也是虚假的值,因此在上面加上条件运算符总是会让您“”“退缩。

const { useState, useEffect } = React;
const { render } = ReactDOM;

const INTRO_TEXT = 'Welcome to Stackoverflow';

function App() {
  const [value, setValue] = useState("");

  useEffect(() => {
    let i = 0;
    const valueInterval = setInterval(() => {
      setValue(oldValue => {
        if (oldValue === INTRO_TEXT) {
          clearInterval(valueInterval);
          return oldValue;
        }
        console.warn(oldValue)
        return oldValue + INTRO_TEXT.charAt(i);
      });
      i++;
    }, 100);

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

  return (
    <p>{value}</p>
  )
}

render(<App />, document.getElementById('root'));
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

<div id="root" />

答案 1 :(得分:0)

const [value, setValue] = useState<string | undefined>("");
const [displayedValue, setDisplayedValue] = useState<string | undefined>("");

useEffect(() => {
  clearInterval(window.myInterval);
  let i = 0 
  const valueArr = value.split('')
  window.myInterval = setInterval(() => {
    const newVal = displayedValue + valueArr[i]
    setDisplayedValue(newVal)
    i++
  }, 100);
}, [value]);