Как сохранить значение переменной внутри функционального компонента - PullRequest
0 голосов
/ 12 октября 2019

У меня есть переменная myinterval внутри functional component с Крюками , и я обновляю и присваиваю новое значение это myinterval, только внутри useEffect.

Но после обновления состояния myinterval содержит предыдущее значение, я имею в виду значение, которое я инициализировал внутри функциональных компонентов.

function App(props) {

  const [name, setName] = useState('Muhammad');

  let myinterval = null;

  useEffect(()=>{

    myinterval = setInterval(()=> {}, 100);

  }, []);

  const print = async () => {
    setName('new name');
     console.log(myinterval);
  };

  return <button className="App" onClick={print}>hey</button>;
}

Теперь, как вы можете видеть, когда я нажимаю print функция , в первый раз она не равна нулю, но во второй раз она равна нулю.

Это происходит из-за setName('new name');, фактически после вызова setName('new name');, затем myinterval возвращает нулевое значение.

Что я хочу?

Я хочу, чтобы myinterval переменная всегда возвращала значение, которое повторно инициализировалось внутри useEffect.

Согласномоя потребность, я не могу объявить свою переменную myinterval вне function App(props){}.

Вот пример, который я показал, это очень просто. Пример простого кода

Ответы [ 2 ]

1 голос
/ 12 октября 2019

Это установит интервал только при первом рендеринге и отменит его при размонтировании

useEffect(()=>{
    myinterval = setInterval(()=> {}, 100);
    return () => clearInterval(myInterval)
  }, []);
}

Если вы хотите сохранить ссылку на идентификатор интервала, вы не должны использовать обычную переменную (которая установлена ​​вкаждый рендер), но лучше использовать ссылку React с хуком useRef

function App(props) {

  const [name, setName] = useState('Muhammad');

  const myInterval = useRef(null)

  useEffect(()=>{
    myinterval.current = setInterval(()=> {}, 100);
    return () => {
      if (myInterval.current) { 
        clearInterval(myInterval.current)
        myInterval.current = null
      }
    }
  }, []);

  const print = async () => {
    setName('new name');
     console.log(myinterval.current);
  };

  return <button className="App" onClick={print}>hey</button>;
}
1 голос
/ 12 октября 2019
let myinterval = null;

запускается каждый раз, при каждом рендеринге

useEffect(()=>{
    myinterval = setInterval(()=> {}, 100);
}, []);

запускается только при монтировании, оставляя myinterval со значением null

Исправление того, что вы хотите достичь:

import React, { useState, useEffect, useMemo } from "react";
import ReactDOM from "react-dom";

import "./styles.css";

function App() {
  const [name, setName] = useState("Muhammad");
  const [timeout, setTimeout] = useState("init value");

  useEffect(() => {
    setInterval(() => setTimeout("new value"), 3000);
  }, []);

  const print = async () => {
    setName("setting name");
    console.log(timeout);
  };

  return (
    <button className="App" onClick={print}>
      hey
    </button>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
...