Redux Thunk中使用AsyncStorage时Action无法派发的问题求助
Let's break down what's causing your dispatch issues and fix this code properly:
What's Wrong With Your Current Code
Incorrect Promise
.then()Usage:
You're directly invokingthis.props.dispatch(isLoadingCredentials(true))inside the first.then()instead of passing a callback function. This means theisLoadingCredentials(true)action gets dispatched immediately—beforeAsyncStorage.getItem()finishes its async operation. The.then()method expects a function to run when the Promise resolves, but you're passing the result ofdispatch()(an action object) instead.Broken Promise Chaining:
Dispatch calls return the action object they dispatched, not a Promise. So when you chain.then()afterthis.props.dispatch(setCredentials(...)), those subsequent.then()calls won't wait for any async logic (there isn't any here) and will execute immediately, leading to unexpected order of operations.
Fixed Solutions
Option 1: Clean Promise Chaining
componentWillMount() { // Start loading before fetching data this.props.dispatch(isLoadingCredentials(true)); AsyncStorage.getItem("loggedIn") .then(data => { if (data) { this.props.dispatch(setCredentials(JSON.parse(data))); this.props.dispatch(navigate("Month")); } }) .catch(error => { // Handle any errors from AsyncStorage console.error("Failed to load credentials:", error); }) .finally(() => { // Stop loading regardless of success/failure this.props.dispatch(isLoadingCredentials(false)); }); }
Option 2: Async/Await (More Readable)
Async/await makes async code look synchronous, which is easier to follow:
async componentWillMount() { this.props.dispatch(isLoadingCredentials(true)); try { const data = await AsyncStorage.getItem("loggedIn"); if (data) { this.props.dispatch(setCredentials(JSON.parse(data))); this.props.dispatch(navigate("Month")); } } catch (error) { console.error("Failed to load credentials:", error); } finally { this.props.dispatch(isLoadingCredentials(false)); } }
Additional Notes
- Avoid
componentWillMount: React has markedcomponentWillMountas unsafe in newer versions (16.3+). It's better to move this logic tocomponentDidMountinstead, since it runs after the component mounts and is safer for async operations. - Verify Connect Setup: Double-check that your
mapDispatchToPropsis correctly set up (or that you're using theconnectfunction correctly to injectdispatchinto props). If you didn't definemapDispatchToProps,connectwill automatically passdispatchas a prop, which it looks like you're using correctly.
内容的提问来源于stack exchange,提问作者Bomber

