我正在尝试新的React钩子,并有一个时钟组件,它的时间值应该每秒钟增加。但是,该值不会超过1。
function Clock() {
const [time, setTime] = React.useState(0);
React.useEffect(() => {
const timer = window.setInterval(() => {
setTime(time + 1);
}, 1000);
return () => {
window.clearInterval(timer);
};
}, []);
return (
<div>Seconds: {time}</div>
);
}
ReactDOM.render(<Clock />, document.querySelector('#app'));
<script src="https://unpkg.com/react@16.7.0-alpha.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.development.js"></script>
<div id="app"></div>
当提供空输入列表时,useEffect函数只在组件挂载时计算一次。
setInterval的另一个替代方法是在每次状态更新时使用setTimeout设置新的间隔时间:
const [time, setTime] = React.useState(0);
React.useEffect(() => {
const timer = setTimeout(() => {
setTime(time + 1);
}, 1000);
return () => {
clearTimeout(timer);
};
}, [time]);
setTimeout对性能的影响很小,一般可以忽略。除非组件对时间敏感,以至于新设置的超时会导致不良影响,否则setInterval和setTimeout方法都是可以接受的。
在某种程度上类似的问题,但当使用状态值时,状态值是一个对象,并且不更新。
我有一些问题,所以我希望这可以帮助到一些人。
我们需要传递与新对象合并的旧对象
const [data, setData] = useState({key1: "val", key2: "val"});
useEffect(() => {
setData(...data, {key2: "new val", newKey: "another new"}); // --> Pass old object
}, []);
我从这个博客上抄了代码。所有功劳归于船主。https://overreacted.io/making-setinterval-declarative-with-react-hooks/
唯一的事情是,我把这个React代码改编为React Native代码,所以如果你是一个React Native编码器,只要复制这个,并适应你想要的。很容易适应吧!
import React, {useState, useEffect, useRef} from "react";
import {Text} from 'react-native';
function Counter() {
function useInterval(callback, delay) {
const savedCallback = useRef();
// Remember the latest function.
useEffect(() => {
savedCallback.current = callback;
}, [callback]);
// Set up the interval.
useEffect(() => {
function tick() {
savedCallback.current();
}
if (delay !== null) {
let id = setInterval(tick, delay);
return () => clearInterval(id);
}
}, [delay]);
}
const [count, setCount] = useState(0);
useInterval(() => {
// Your custom logic here
setCount(count + 1);
}, 1000);
return <Text>{count}</Text>;
}
export default Counter;