反应上下文传递时间每秒发生无限循环

问题描述 投票:0回答:2

抱歉,我是React的新手,所以我遇到了一个问题,那就是我的Context为其他组件提供了时间。当我仅将其与显示时钟的组件一起使用时,一切都很好。问题出现在另一个组件中,我想根据一天中的时间显示消息。 重新渲染过多。 React限制了渲染次数以防止无限循环。

我的上下文组件

import React, { createContext, useState, useEffect } from "react";
import moment from "moment";

export const GreetingContext = createContext();

const getTime = () => {
  return moment();
};

const GreetingContextProvider = (props) => {
  const [currentTime, setCurrentTime] = useState(getTime);


  const setTime = () => {
    setInterval(() => {
      setCurrentTime(getTime);
    }, 1000);

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

  return (
    <GreetingContext.Provider value={currentTime}>
      {props.children}
    </GreetingContext.Provider>
  );
};

export default GreetingContextProvider;

和我的消息组件

import React, { useState, useContext} from "react";
import { useLocalStorage } from "../custome_hooks/useLocalStorage";
import { GreetingContext } from "../contexts/GreetingContext";

const Greeting = () => {
  const time = useContext(GreetingContext);
  const timeInHours = time.hours();
  const [greeting, setGreeting] = useState("ooo");
  const [name, setName] = useLocalStorage("name", "Your name");


// Setting the greeting depending on the time of the day
  switch (true) {
    case timeInHours > 0 && timeInHours < 5:
        setGreeting("Good night");
      break;
    case timeInHours > 5 && timeInHours < 12:
        setGreeting("Good morning");
      break;
    case timeInHours > 12 && timeInHours < 17:
        setGreeting("Good day");
      break;
      case timeInHours > 17 && timeInHours < 24:
        setGreeting("Good evening");
      break;
    default:
        setGreeting("");
  }



  // Getting the name of the user
  let handleChange = (e) => {
    setName(e.target.value);
  };

  return (
    <div className="greeting_container">
      <h4>{greeting}</h4>
      <input
        type="text"
        size={name.length + 1}
        value={name}
        onChange={handleChange}
      />
    </div>
  );
};

export default Greeting;

谢谢

reactjs settimeout setinterval infinite-loop use-context
2个回答
0
投票

[好吧,我通过将我的Switch()传递到带有我已添加到消息组件的第二个参数的useEffect挂钩中,解决了该问题。

useEffect(() => {
    switch (true) {
      case timeInHours > 0 && timeInHours < 5:
        setGreeting("Good night");
        break;
      case timeInHours > 5 && timeInHours < 12:
        setGreeting("Good morning");
        break;
      case timeInHours > 12 && timeInHours < 17:
        setGreeting("Good day");
        break;
      case timeInHours > 17 && timeInHours < 24:
        setGreeting("Good evening");
        break;
      default:
        setGreeting("");
    }
  }, [timeInHours]);

因此,只有在timeInHours变量更改的情况下,组件才会每秒更新一次。


0
投票

我认为您的问题是开始setInterval的useEffect

应该是:

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

还有在更新时间时,也应该调用该函数。

setCurrentTime(getTime()); // <-- add () to getTime
// same for useState
useState(getTime());

编辑:

我知道这以另一种方式回答了您的问题,但是我还是让您迷恋了上下文:

import { useState, useEffect } from 'react';
import moment from 'moment';

const getTime = () => moment();

export default () => {
    const [currentTime, setCurrentTime] = useState(getTime());

    const setTime = setInterval(() => {
            setCurrentTime(getTime());
        }, 1000);

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

    return currentTime;
}

并照常使用:const currentTime = useTime()

© www.soinside.com 2019 - 2024. All rights reserved.