反应(下一步)等待上下文数据并将值传递给自定义挂钩
react (next) wait context data and passing values to custom hook
我正在尝试将上下文中的数据消费到自定义挂钩中。问题是数据没有准备好,挂钩采用默认值。
上下文准备好后,如何让我的自定义挂钩采用更新的值?
定时器上下文
the context expects two values that I get from the database
//context
export const TimerContext = createContext();
//hook
export const useTimer = () => useContext(TimerContext);
//provider
export const TimerProvider = ({ children }) => {
//estado del context
const [timer, setTimer] = useState({
inicioPartido: "Apr 8, 2022 01:00:00",
finPartido: "Apr 8, 2022 01:10:00",
});
return (
<TimerContext.Provider value={{ timer, setTimer }}>
{children}
</TimerContext.Provider>
);
};
页数index.js
timers it is an object that I get from the database, here everything works fine
the object exists and is stored in the context
const {timer, setTimer } = useTimer();
useEffect(() => {
setTimer({
inicioPartido: timers.start_timer,
finPartido: timers.end_timer,
});
}, [timers]);
问题
when I pass both dates to my custom hook, it gets only the default values that I put in the context
const { inicio, termino, segundo, minuto, hora, dia } = useCounterhook(
timer.inicioPartido,
timer.finPartido
);
改为
If I send the dates hard coded everything works perfectly
const { inicio, termino, segundo, minuto, hora, dia } = useCounterhook(
"Apr 8, 2022 03:40:00",
"Apr 8, 2022 03:50:00"
);
我的自定义挂钩
my hook compares the distance between two dates and generates a countdown
import React, { useState, useEffect } from "react";
import PropTypes from "prop-types";
const useCounterhook = (fechaInicio, fechaTermino) => {
//states
const [segundo, setSegundo] = useState(0);
const [minuto, setMinuto] = useState(0);
const [hora, setHora] = useState(0);
const [dia, setDia] = useState(0);
const [inicio, setInicio] = useState(false);
const [termino, setTermino] = useState(false);
//real time settings
const second = 1000;
const minute = second * 60;
const hour = minute * 60;
const day = hour * 24;
useEffect(() => {
setInterval(() => {
let inicio = new Date(fechaInicio).getTime();
let termino = new Date(fechaTermino).getTime();
let ahora = new Date().getTime();
let distance = inicio - ahora;
if (inicio > ahora && termino > ahora) {
//si fechaInicio es mayor a este instante
//partido aun no inicia
setDia(Math.floor(distance / day));
setHora(Math.floor((distance % day) / hour));
setMinuto(Math.floor((distance % hour) / minute));
setSegundo(Math.floor((distance % minute) / second));
setInicio(false);
setTermino(false);
}
if (inicio < ahora && termino > ahora) {
//si fecha inicio es menor a este instante
// partido ya inicio y aun no termina
setDia(0);
setHora(0);
setMinuto(0);
setSegundo(0);
setInicio(true);
setTermino(false);
}
if (inicio < ahora && termino < ahora) {
//si fecha inicio es mayor a fecha de termino
//el partido ya termino
setDia(0);
setHora(0);
setMinuto(0);
setSegundo(0);
setInicio(false);
setTermino(true);
}
}, 1000);
}, []);
return { inicio, termino, segundo, minuto, hora, dia };
};
export default useCounterhook;
useCounterhook.propTypes = {
fechaInicio: PropTypes.string,
fechaTermino: PropTypes.string,
};
我认为是上下文没有准备好,当hook已经在等待值的时候,但是不知道怎么解决
这里的问题是,useCounterHook
是 运行,useEffect
是基于第一次安装的,然后从不考虑 timer
值何时更改.
如果你使用 useEffect
依赖数组你可以解决这个问题。
将 useCounterHook
中的 useEffect
更新为以下内容,您应该可以开始了:
useEffect(() => {
const interval = setInterval(() => {
// this content doesn't change
}, 1000);
// useEffect's cleanup method
return () => {
clearInterval(interval)
}
// dependency array to listen if `fetchaInicio` or `fetchTermino` changes
}, [fechaInicio, fechaTermino]);
现在您的钩子将检查这些输入中的任何一个是否发生变化,如果是这种情况,计时器将停止,然后使用新值启动一个新计时器。
我正在尝试将上下文中的数据消费到自定义挂钩中。问题是数据没有准备好,挂钩采用默认值。 上下文准备好后,如何让我的自定义挂钩采用更新的值?
定时器上下文
the context expects two values that I get from the database
//context
export const TimerContext = createContext();
//hook
export const useTimer = () => useContext(TimerContext);
//provider
export const TimerProvider = ({ children }) => {
//estado del context
const [timer, setTimer] = useState({
inicioPartido: "Apr 8, 2022 01:00:00",
finPartido: "Apr 8, 2022 01:10:00",
});
return (
<TimerContext.Provider value={{ timer, setTimer }}>
{children}
</TimerContext.Provider>
);
};
页数index.js
timers it is an object that I get from the database, here everything works fine the object exists and is stored in the context
const {timer, setTimer } = useTimer();
useEffect(() => {
setTimer({
inicioPartido: timers.start_timer,
finPartido: timers.end_timer,
});
}, [timers]);
问题
when I pass both dates to my custom hook, it gets only the default values that I put in the context
const { inicio, termino, segundo, minuto, hora, dia } = useCounterhook(
timer.inicioPartido,
timer.finPartido
);
改为
If I send the dates hard coded everything works perfectly
const { inicio, termino, segundo, minuto, hora, dia } = useCounterhook(
"Apr 8, 2022 03:40:00",
"Apr 8, 2022 03:50:00"
);
我的自定义挂钩
my hook compares the distance between two dates and generates a countdown
import React, { useState, useEffect } from "react";
import PropTypes from "prop-types";
const useCounterhook = (fechaInicio, fechaTermino) => {
//states
const [segundo, setSegundo] = useState(0);
const [minuto, setMinuto] = useState(0);
const [hora, setHora] = useState(0);
const [dia, setDia] = useState(0);
const [inicio, setInicio] = useState(false);
const [termino, setTermino] = useState(false);
//real time settings
const second = 1000;
const minute = second * 60;
const hour = minute * 60;
const day = hour * 24;
useEffect(() => {
setInterval(() => {
let inicio = new Date(fechaInicio).getTime();
let termino = new Date(fechaTermino).getTime();
let ahora = new Date().getTime();
let distance = inicio - ahora;
if (inicio > ahora && termino > ahora) {
//si fechaInicio es mayor a este instante
//partido aun no inicia
setDia(Math.floor(distance / day));
setHora(Math.floor((distance % day) / hour));
setMinuto(Math.floor((distance % hour) / minute));
setSegundo(Math.floor((distance % minute) / second));
setInicio(false);
setTermino(false);
}
if (inicio < ahora && termino > ahora) {
//si fecha inicio es menor a este instante
// partido ya inicio y aun no termina
setDia(0);
setHora(0);
setMinuto(0);
setSegundo(0);
setInicio(true);
setTermino(false);
}
if (inicio < ahora && termino < ahora) {
//si fecha inicio es mayor a fecha de termino
//el partido ya termino
setDia(0);
setHora(0);
setMinuto(0);
setSegundo(0);
setInicio(false);
setTermino(true);
}
}, 1000);
}, []);
return { inicio, termino, segundo, minuto, hora, dia };
};
export default useCounterhook;
useCounterhook.propTypes = {
fechaInicio: PropTypes.string,
fechaTermino: PropTypes.string,
};
我认为是上下文没有准备好,当hook已经在等待值的时候,但是不知道怎么解决
这里的问题是,useCounterHook
是 运行,useEffect
是基于第一次安装的,然后从不考虑 timer
值何时更改.
如果你使用 useEffect
依赖数组你可以解决这个问题。
将 useCounterHook
中的 useEffect
更新为以下内容,您应该可以开始了:
useEffect(() => {
const interval = setInterval(() => {
// this content doesn't change
}, 1000);
// useEffect's cleanup method
return () => {
clearInterval(interval)
}
// dependency array to listen if `fetchaInicio` or `fetchTermino` changes
}, [fechaInicio, fechaTermino]);
现在您的钩子将检查这些输入中的任何一个是否发生变化,如果是这种情况,计时器将停止,然后使用新值启动一个新计时器。