我是新来的反应者,我才刚刚开始学习钩子和上下文。
我正在使用以下代码从API获取一些数据:
const getScreen = async uuid => {
const res = await axios.get(
`${url}/api/screen/${uuid}`
);
dispatch({
type: GET_SCREEN,
payload: res.data
});
};
继续使用减速器。
case GET_SCREEN:
return {
...state,
screen: action.payload,
};
在Screen.js中,我正在呼叫getScreen
并发送UUID
以显示确切的屏幕。效果很好。我遇到的问题是当我尝试获取API(每3秒进行测试)并根据其从API检索的内容更新nodeupdated
的状态时。问题是,screen.data
始终是未定义的(由于它是异步的?)
import React, {
useState,
useEffect,
useContext,
} from 'react';
import SignageContext from '../../context/signage/signageContext';
const Screen = ({ match }) => {
const signageContext = useContext(SignageContext);
const { getScreen, screen } = signageContext;
const [nodeupdated, setNodeupdated] = useState('null');
const foo = async () => {
getScreen(match.params.id);
setTimeout(foo, 3000);
};
useEffect(() => {
foo();
setNodeupdated(screen.data)
}, []);
如果我删除了[],则实际上是从api中获取数据...但是处于无限循环中。
问题是,在我将其转换为钩子之前,这似乎工作得很好:
componentDidMount() {
// Get screen from UUID in url
this.props.getScreen(this.props.match.params.id);
// Get screen every 30.5 seconds
setInterval(() => {
this.props.getScreen(this.props.match.params.id);
this.setState({
nodeUpdated: this.props.screen.data.changed
});
}, 3000);
}
答案 0 :(得分:0)
使用自定义钩子,例如useInterval
function useInterval(callback, delay) {
const savedCallback = useRef();
useEffect(() => {
savedCallback.current = callback;
});
useEffect(() => {
function tick() {
savedCallback.current();
}
let id = setInterval(tick, delay);
return () => clearInterval(id);
}, [delay]);
}
然后在您的组件中
useInterval(() => {
setCount(count + 1);
}, delay);
Dan Abramov有一篇很棒的博客文章
https://overreacted.io/making-setinterval-declarative-with-react-hooks/
答案 1 :(得分:0)
您可以使用类似这样的东西。只需用您的API请求替换console.log。
useEffect(() => {
const interval = setInterval(() => {
console.log("Making request");
}, 3000);
return () => clearInterval(interval);
}, []);
或者,替换foo
,useEffect
并添加requestId
const [requestId, setRequestId] = useState(0);
const foo = async () => {
getScreen(match.params.id);
setTimeout(setRequestId(requestId+1), 3000);
};
useEffect(() => {
foo();
setNodeupdated(screen.data)
}, [requestId]);