在异步调用之前更新状态的正确方法
Posted
技术标签:
【中文标题】在异步调用之前更新状态的正确方法【英文标题】:Correct Way to Update Sate before Async call 【发布时间】:2022-01-23 07:32:12 【问题描述】:我正在尝试更新状态以在进行异步调用时显示 ActivityIndicator。
确保IsLoading(true)
和setResult(null)
在异步调用之前发生的正确方法是什么?
在下面的代码中,setIsLoading
在异步调用之前实际上并未更新,因此 ActivityIndicator 不会出现在 UI 上。我意识到为什么会出现这种情况 (here) 我只是不知道在进行异步调用之前实际确保 ActivityIndicator 显示的推荐方法。
请帮忙。在反应中做到这一点的正确方法是什么?
const MyScreen = () =>
const [isLoading, setIsLoading] = useState(false);
const [result, setResult] = useState(null);
const handlePress = async () =>
setResult(null); // reset result
setIsLoading(true); // show activity indicator
const result = await MyAsyncFunc(); // native modules function
setResult(result);
setIsLoading(false); // turn off activity indicator
return (
<View style=styles.container>
<MyButton title="Run" handlePress=handlePress disabled=isLoading />
isLoading && <ActivityIndicator size="large" color="#00ff00" />
<Text>result</Text>
</View>
)
const styles = StyleSheet.create(
container:
flex: 1,
alignItems: 'center',
justifyContent: 'center'
,
)
【问题讨论】:
【参考方案1】:尝试添加useEffect
并在更改result
依赖项时设置isLoading
false,如下所示:
const MyScreen = () =>
const [isLoading, setIsLoading] = useState(false);
const [result, setResult] = useState(null);
const handlePress = async () =>
setResult(null); // reset result
setIsLoading(true); // show activity indicator
const result = await MyAsyncFunc(); // native modules function
setResult(result);
//setIsLoading(false); // turn off activity indicator
useEffect(() =>
if(result && isLoading)
setIsLoading(false);
, [isLoading, result])
return (
<View style=styles.container>
<MyButton title="Run" handlePress=handlePress disabled=isLoading />
isLoading && <ActivityIndicator size="large" color="#00ff00" />
<Text>result</Text>
</View>
)
希望这对你有用
【讨论】:
感谢您的回复,但我在运行此代码时看到了同样的问题。我认为 idiglove 上面的回答通过将MyAsyncFunc
放入 useEffect that listens to changes on
isLoading. This guarantees that
isLoading` 将在 MyAsyncFunc
运行之前更改,从而解决了这个问题。【参考方案2】:
您可以尝试只使用一种状态吗?我认为不需要isLoading
。
试试这个
!result && <ActivityIndicator size="large" color="#00ff00" />
编辑:让我们利用 useEffect 来监听 isLoading 是否为真
...
useEffect(() =>
async function load ()
if (isLoading)
const result = await MyAsyncFunc(); // native modules function
setResult(result);
setIsLoading(false); // turn off activity indicator
load()
, [isLoading])
const handlePress = () =>
setResult(null); // reset result
setIsLoading(true); // show activity indicator
【讨论】:
当用户第一次访问屏幕时,result
将为空,我会不喜欢显示的 ActivityIndicator。他们会按下按钮来触发异步功能。
感谢您的编辑。这样可行!我学到了一些东西:D以上是关于在异步调用之前更新状态的正确方法的主要内容,如果未能解决你的问题,请参考以下文章