只有在异步操作完成后才导航到下一页?反应母语

时间:2017-11-08 13:40:57

标签: react-native redux

所以,对于我来说,作为初学者,还有redux和react-native,我有点棘手。

当用户登录时,我想用用户数据更新Redux状态。我调用登录方法获取Web令牌。之后我想用redux-thunk调度两个异步动作。问题是:

当调度这些操作并且我得到API的响应时,我已经导航到另一个屏幕,并且呈现列表的数据不处于Redux状态。

问题:如果我的状态更新,然后导航到下一页,我该如何“保留”该程序?

这是用户登录时发生的情况:

 fetch("http://10.0.2.2:8000/api/api-token-auth/", {
        method: "post",
        headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({
          email: this.props.email,
          password: this.props.password,
        })
        }).then((response) => response.json()
        ).then((jResponse) => {
          console.log(jResponse);
          this._onValueChange('token_id', jResponse.token);
          this.props.loginUserSuccess();
          this.props.navigation.navigate('MainMenue');
        }).catch((error) => {
          console.log(error);
          this.props.loginUserFail();
          })   
    }

在登录期间的某个地方,这两个动作应该完全分派,状态应该更新:

export const profileLoad = () => {       

        return (dispatch) => {
            AsyncStorage.getItem('token_id')
            .then((token_id) => fetch("http://10.0.2.2:8000/api/profile/", {
                method: "GET",
                headers: {
                'Authorization': 'JWT ' + token_id
                }
            })
            .then((response) => response.json())
            .then((answer) => {
                dispatch({ type: PROFILE_LOAD, payload: answer});
            })
            .done());
        }  
    }

export const productsLoad = () => {

    return (dispatch) => {
        AsyncStorage.getItem('token_id')
        .then((token_id) => {

            fetch("http://10.0.2.2:8000/api/profile/products/", {
                method: "GET",
                headers: {
                'Authorization': 'JWT ' + token_id
                }
            }).then((anser) => anser.json())
            .then((response)=> {
                dispatch ({ type: PRODUCTS_LOAD, payload: response})
            })
        }
        ).done();
    }  

}

然后我想浏览另一个屏幕并找到一个列表(使用ListView)以显示产品和配置文件中的JSON数据。

- >所以我终于明白了。 的解决方案 1.)如所述,返回行动创作者的承诺 2.)确保在then方法中放置一个回调函数

export const loadAllProfileData = ({navigate}) => {
    return (dispatch) => {
        dispatch(profileLoad())
        .then(() => dispatch(productsLoad()))
        .then(() => navigate('MainMenue'))
    };
}

export const profileLoad = () => {       

            return (dispatch) => {
                return AsyncStorage.getItem('token_id')
                .then((token_id) => fetch("http://10.0.2.2:8000/api/profile/", {
                    method: "GET",
                    headers: {
                    'Authorization': 'JWT ' + token_id
                    }
                })
                ).then((response) => response.json())
                .then((answer) => {
                    dispatch({ type: PROFILE_LOAD, payload: answer});
                })

            }  
        }


export const productsLoad = () => {

     return (dispatch) => {
         return AsyncStorage.getItem('token_id')
         .then((token_id) => 
             fetch("http://10.0.2.2:8000/api/profile/products/", {
                 method: "GET",
                 headers: {
                 'Authorization': 'JWT ' + token_id
                 }
            })
        ).then((answer) => answer.json())
        .then((response)=> {
                dispatch ({ type: PRODUCTS_LOAD, payload: response})
            }) 

     }  
}

1 个答案:

答案 0 :(得分:1)

您可以使用chain从您的操作创建者和then返回承诺。只需将return AsyncStorage.getItem() ...添加到您的操作创建者即可。然后你可以这样做:

fetch(url) //login
  .then(dispatch(profileLoad))
  .then(dispatch(productsLoad))
  .then(this.props.navigation.navigate('MainMenue'))
  .catch(err => //handle error)

详细了解promises chaining

编辑:一个简单的例子是:

import { createStore, applyMiddleware } from 'redux'
import thunkMiddleware from 'redux-thunk'
import fetch from 'node-fetch';

const ROOT_URL = 'https://jsonplaceholder.typicode.com';

const FETCH_DATA = 'FETCH_DATA';

const url = `${ROOT_URL}/users`;

function fetchData() {
    return (dispatch) => {
        return fetch(url)
            .then(res => res.json())
            .then(data => {
                dispatch({
                    type: FETCH_DATA,
                    payload: data[0].name
                });
            }) 
    }
}

function reducer(state = [], action) {
    if (action.type === FETCH_DATA) {
        console.log('Action.payload:', action.payload);
    }

    switch (action.type) {
        case 'FETCH_DATA':
            return [...state, action.payload];

        default:
            return state;
    };
}

let store = createStore(
    reducer,
    applyMiddleware(thunkMiddleware)
)

store.subscribe(() =>
    console.log('Store State: ', store.getState())
)

fetch(url)
    .then(res => res.json())
    .then(data => data)
    .then(store.dispatch(fetchData()))
    .then(store.dispatch(fetchData()))