Javascript 如何在React原生应用程序中使用React hook useEffect设置每5秒渲染的间隔?
我有Javascript 如何在React原生应用程序中使用React hook useEffect设置每5秒渲染的间隔?,javascript,react-native,setinterval,react-hooks,use-effect,Javascript,React Native,Setinterval,React Hooks,Use Effect,我有React Native应用程序,我通过fetch从API获取数据。我创建了从API获取数据的自定义钩子。我需要每5秒重新渲染一次。为此,我将我的自定义钩子包装到setInterval,在我的应用程序变得工作非常缓慢之后,当我导航到另一个屏幕时,我得到以下错误: 无法对未安装的组件执行React状态更新。这是 无操作,但表示应用程序内存泄漏。要解决, 取消useEffect清理中的所有订阅和异步任务 功能 您能告诉我如何解决这个错误,以及哪种方法是设置间隔的最佳方法,因为我认为我的方法不好
React Native
应用程序,我通过fetch
从API
获取数据。我创建了从API
获取数据的自定义钩子。我需要每5秒重新渲染一次。为此,我将我的自定义钩子包装到setInterval,在我的应用程序变得工作非常缓慢之后,当我导航到另一个屏幕时,我得到以下错误:
无法对未安装的组件执行React状态更新。这是 无操作,但表示应用程序内存泄漏。要解决, 取消useEffect清理中的所有订阅和异步任务 功能 您能告诉我如何解决这个错误,以及哪种方法是设置间隔的最佳方法,因为我认为我的方法不好 我的自定义挂钩:
export const useFetch = url => {
const [state, setState] = useState({ data: null, error: false, loading: true })
useEffect(() => {
setInterval(() => {
setState(state => ({ data: state.data, error: false, loading: true }))
fetch(url)
.then(data => data.json())
.then(obj =>
Object.keys(obj).map(key => {
let newData = obj[key]
newData.key = key
return newData
})
)
.then(newData => setState({ data: newData, error: false, loading: false }))
.catch(function(error) {
console.log(error)
setState({ data: null, error: true, loading: false })
})
}, 5000)
}, [url, useState])
useEffect(() => () => console.log('unmount'), [])
return state
}
const ChartsScreen = ({ navigation }) => {
const { container } = styles
const url = 'https://poloniex.com/public?command=returnTicker'
const { data, error, loading } = useFetch(url)
const percentColorHandler = number => {
return number >= 0 ? true : false
}
return (
<View style={container}>
<ProjectStatusBar />
<IconsHeader
dataError={false}
header="Charts"
leftIconName="ios-arrow-back"
leftIconPress={() => navigation.navigate('Welcome')}
/>
<ChartsHeader />
<ActivityIndicator animating={loading} color="#068485" style={{ top: HP('30%') }} size="small" />
<FlatList
data={data}
keyExtractor={item => item.key}
renderItem={({ item }) => (
<CryptoItem
name={item.key}
highBid={item.highestBid}
lastBid={item.last}
percent={item.percentChange}
percentColor={percentColorHandler(item.percentChange)}
/>
)}
/>
</View>
)
}
我的组件:
export const useFetch = url => {
const [state, setState] = useState({ data: null, error: false, loading: true })
useEffect(() => {
setInterval(() => {
setState(state => ({ data: state.data, error: false, loading: true }))
fetch(url)
.then(data => data.json())
.then(obj =>
Object.keys(obj).map(key => {
let newData = obj[key]
newData.key = key
return newData
})
)
.then(newData => setState({ data: newData, error: false, loading: false }))
.catch(function(error) {
console.log(error)
setState({ data: null, error: true, loading: false })
})
}, 5000)
}, [url, useState])
useEffect(() => () => console.log('unmount'), [])
return state
}
const ChartsScreen = ({ navigation }) => {
const { container } = styles
const url = 'https://poloniex.com/public?command=returnTicker'
const { data, error, loading } = useFetch(url)
const percentColorHandler = number => {
return number >= 0 ? true : false
}
return (
<View style={container}>
<ProjectStatusBar />
<IconsHeader
dataError={false}
header="Charts"
leftIconName="ios-arrow-back"
leftIconPress={() => navigation.navigate('Welcome')}
/>
<ChartsHeader />
<ActivityIndicator animating={loading} color="#068485" style={{ top: HP('30%') }} size="small" />
<FlatList
data={data}
keyExtractor={item => item.key}
renderItem={({ item }) => (
<CryptoItem
name={item.key}
highBid={item.highestBid}
lastBid={item.last}
percent={item.percentChange}
percentColor={percentColorHandler(item.percentChange)}
/>
)}
/>
</View>
)
}
const chartscreen=({navigation})=>{
常量{container}=样式
常量url=https://poloniex.com/public?command=returnTicker'
const{data,错误,正在加载}=useFetch(url)
const percentColorHandler=number=>{
返回编号>=0?真:假
}
返回(
导航。导航('Welcome')}
/>
item.key}
renderItem={({item})=>(
)}
/>
)
}
您需要清除间隔
useEffect(() => {
const intervalId = setInterval(() => { //assign interval to a variable to clear it.
setState(state => ({ data: state.data, error: false, loading: true }))
fetch(url)
.then(data => data.json())
.then(obj =>
Object.keys(obj).map(key => {
let newData = obj[key]
newData.key = key
return newData
})
)
.then(newData => setState({ data: newData, error: false, loading: false }))
.catch(function(error) {
console.log(error)
setState({ data: null, error: true, loading: false })
})
}, 5000)
return () => clearInterval(intervalId); //This is important
}, [url, useState])
有关
useffect
中的cleanup
函数的更多信息,请参阅。可能是以下两种情况:
- 你需要整理一下你的休息时间
- 如果API回调已卸载,则不需要从API回调更新状态
根据您的服务器响应时间,您可能希望为挂起的查询添加故障保护(例如,如果您发送了一个查询,并且在第一个查询返回之前启动了下一个查询…) 让React Hooks+Apollo每隔5秒从GraphQL服务器获取数据。 在本例中,如果用户未在后端登录,我们将在React中注销该用户。(JWT代币不再有效)
我添加了这两行,但无论如何都有一个错误,应用程序运行非常缓慢。错误是什么?由于设置间隔时间,应用程序运行缓慢,每次都会等待5秒。尝试缩短时间。无法对未安装的组件执行React状态更新。这是一个no-op,但它表示应用程序中存在内存泄漏。若要修复此问题,请取消useEffect清理函数中的所有订阅和异步任务。您的应用程序中是否有其他setInterval?通过这样做
return()=>clearInterval(intervalId)代码>它将清除setInterval。因为我想用于卸载组件。我删除了它,现在效果更好了。非常感谢你。请再告诉我一件事,这个组件在我的tabsNavigator的一个选项卡中呈现,当我更改选项卡组件没有卸载时,呈现仍在工作。只有当我离开导航堆栈时,组件才会卸载。为什么?错误仍然在出现,但不像以前那样频繁