【问题标题】:useReducer returning a promise instead of the updated stateuseReducer 返回一个承诺而不是更新的状态
【发布时间】:2020-04-16 23:16:38
【问题描述】:

我的减速机:

export const initialUserState = {
    username: '',
    address: '',
    token: '',
    address: '',
    loggedIn: false,
    loaded: false,
};

export const userReducer = async (state, action) => {
    try {
        switch (action.type) {
            case 'LOAD':
                try {
                    const value = JSON.parse(await AsyncStorage.getItem('user_info'));
                    const newState = { ...state, ...value, loggedIn: true, loaded: true };
                    console.log('New State:', newState);

                    if (value !== null) {
                        return newState;
                    }
                } catch (error) {
                    return { ...state, loaded: true };
                }
                break;
            default:
                return state;
        }
    } catch (error) {
        console.log(error);
        return state;
    }
};

我的 App.js:

import { userReducer, initialUserState } from './reducer';

const App = () => {
    const [user, dispatch] = useReducer(userReducer, initialUserState);

    useEffect(() => {
        dispatch({ type: 'LOAD', ready: setReady });
    }, []);

    useEffect(() => {
        console.log('state user:', user);
    }, [user]);
}

export default App;

发生的情况是,在 App.js 中,在调用第二个 useEffect 之后,状态会更新并且 user 返回一个 Promise。承诺有多个属性,其中一个是它应该返回的正确状态。它不应该返回状态吗?我做错了吗?

简而言之:

1) 应用启动

2) useEffect 首次调用并具有正确的初始状态

3) 我调用 LOAD 动作来更新状态

4) useEffect 被第二次调用。这次它返回了一个 promise,我猜它应该只返回 store 的更新状态?

【问题讨论】:

  • 您将使用 redux-thunk 进行异步操作并将您的请求移动到操作创建者 github.com/reduxjs/redux-thunk
  • 所以这个问题是在问 React Hooks 的“reducers”而不是 redux,对吧?你可以使用 redux-thunk 和 react hooks 吗?

标签: javascript reactjs react-hooks use-reducer


【解决方案1】:

看起来您传递给useReducer 的函数是async。所有async 函数都返回一个承诺。您需要await 或使用.then 语法从promise 中获取值。这不是第一次通过的承诺,因为它返回初始状态。希望对您有所帮助!

【讨论】:

  • 谢谢,我试过了,而不是返回一个承诺它返回未定义我不知道为什么。正如@bsapaka 提到的,我将逻辑从减速器内部移到外部,并将数据作为有效负载传递。它有效,但现在我无法访问其他组件中的减速器,它总是返回初始状态。我要搬到 Redux。我不需要任何复杂的东西,但我厌倦了在这上面浪费时间。
【解决方案2】:

它返回一个 promise,因为 reducer 是一个异步函数,这是因为等待调用 AsyncStorage

const value = JSON.parse(await AsyncStorage.getItem('user_info'));

您应该将存储获取移动到一个效果挂钩中,然后 dispatch 已解决/拒绝承诺的结果。

移动数据提取的另一个原因是reducer 应该是pure functions(这是一个指向Redux 文档的链接,但这个想法仍然适用于React reducer)。 reducer 应该拥有的唯一数据源是它的stateaction 参数。这允许关于这些参数的确定性行为;给定相同的参数,单独的 reducer 调用应该总是返回相同的结果。

【讨论】:

  • 谢谢,我做到了,我将逻辑从减速器内部移到外部,并将数据作为有效负载传递。它有效,但现在我无法访问其他组件中的减速器,它总是返回初始状态。我要搬到 Redux。我不需要任何复杂的东西,但我厌倦了在这上面浪费时间。
  • 如果您在其他组件中需要该状态,请将减速器向上移动,直到所有需要数据的组件都在具有减速器的组件下
猜你喜欢
  • 1970-01-01
  • 2016-07-22
  • 2017-01-03
  • 2019-12-02
  • 2015-11-27
  • 2021-04-11
  • 2021-01-29
  • 2016-02-04
相关资源
最近更新 更多