Asyncstorage в действии Redux

#react-native #redux #react-redux

#react-native #redux #реагировать-redux

Вопрос:

Я пытаюсь использовать свой токен доступа (хранящийся в Asyncstorage) в действии Redux. Это мой код:

 export function fetchData() {
  const endpoint = 'someEndpoint.com';
  let accessToken = '';
  myAccessToken().then((token) => {
    accessToken = token;
  });

  return (dispatch) => {
    dispatch(getData());
    axios.get(endpoint, { headers: { 'access-token': accessToken } })
    .then(response => {
      dispatch(getDataSuccess(response.data));
    })
    .catch(error => {
      dispatch(getDataFailure(error));
    });
  };
}
  
 const myAccessToken = async () => {
  try {
    const retrievedItem = await AsyncStorage.getItem('accessToken');
    return retrievedItem;
  } catch (error) {
    return null;
  }
};
  

Но извлечение ключа, очевидно, асинхронно, я не уверен, как использовать accessToken в вызове API. Мне не разрешено делать что-то подобное:

 export function fetchData() {
  const endpoint = 'someEndpoint.com';
  myAccessToken().then((token) => {
    return (dispatch) => {
      dispatch(getData());
      axios.get(endpoint, { headers: { 'access-token': token } })
      .then(response => {
        dispatch(getDataSuccess(response.data));
      })
      .catch(error => {
        dispatch(getDataFailure(error));
      });
    };
  });
}
  

Мой магазин:

 import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import app from './reducers';

export default function configureStore() {
  return createStore(app, applyMiddleware(thunk));
}
  

Обновить

В конце я сделал это немного по-другому, в моем componentDidMount :

 componentDidMount() {
    AsyncStorage.getItem('accessToken').then((accessToken) => {
      this.setState({ accessToken });
      this.props.fetchData(accessToken);
    });
  }
  

Спасибо, Кевин.

Ответ №1:

Я думаю, вам следует использовать redux-thunk библиотеку для асинхронных обновлений состояния redux. Его легко настроить в store.js файл:

 import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './reducers/index';

// Note: this API requires redux@>=3.1.0
const store = createStore(
  rootReducer,
  applyMiddleware(thunk)
);
  

Тогда я бы реализовал это следующим образом:

 export function fetchData() {
  return async function(dispatch) {
     const endpoint = 'someEndpoint.com';
     const accessToken = await myAccessToken();
     try {
        const response = await axios.get(endpoint, { headers: { 'access-token': accessToken } });
        return dispatch(getDataSuccess(response.data));
     } catch (error) {
        return dispatch(getDataFailure(error));
     }
  }
}
  

Комментарии:

1. Привет @alexgomez0120! Я попробовал ваше предложение, которое приводит к следующей ошибке: error: Actions must be plain objects. Use custom middleware for async actions. (I already had реализован redux-thunk)

2. @KevinEtore Я отредактировал свой ответ, предполагая, что fetchData() это создатель действия, который возвращает функцию в качестве действия.

3. Примите также во внимание, что getDataSuccess() getDataFailure() функции and должны возвращать объект с типом действия redux, например: {type: "FETCH_SUCCESS", data: {} }

4. спасибо за вашу помощь! Я обновил свой вопрос текущим решением!