簡體   English   中英

在渲染任何組件之前使用數據對本機+ Redux填充存儲區進行反應

[英]React native + redux populate store with data before any Component render

我是新來的反應本機+還原。 我有一個反應本機應用程序,其中用戶的第一個屏幕是登錄名,登錄后顯示來自服務器的類別列表頁面。 要獲取類別列表,需要傳遞身份驗證令牌,該身份驗證令牌是從登錄屏幕獲取的,或者如果他之前從AsyncStorage登錄,則可以獲取。

因此,在重新分配任何組件之前,我將創建存儲並手動分派fetchProfile()這樣的操作。

const store = createStore(reducer);
store.dispatch(fetchProfile());

因此,fetchProfile()嘗試從AsyncStorage讀取配置文件數據,並使用數據調度操作。

  export function fetchProfile() {
    return dispatch => {
      AsyncStorage.getItem('@myapp:profile')
        .then((profileString) => {
          dispatch({
            type: 'FETCH_PROFILE',
            profile: profileString ? JSON.parse(profileString) :  {}
          })
        })
    }
  }

因此,在填充商店之前,必須先渲染登錄頁面。 因此,我使用react-redux的connect方法訂閱存儲更改並有條件地加載登錄頁面。

 class MyApp extends React.Component {
    render() {
      if(this.props.profile)
        if(this.props.profile.authentication_token)
          retunr (<Home />);
    else
          return (<Login />);
      else
        return (<Loading />);
    }
  }

  import { connect } from 'react-redux';

  const mapStateToProps = (state) => {
    return {
      profile: state.profile
    }
  }

  module.exports = connect(mapStateToProps, null)(MyApp);

因此,首先渲染“正在加載”組件,然后填充商店,然后渲染“登錄”或“主頁”組件。 那么這是正確的流程嗎? 還是有一種方法可以讓我在進行任何組件渲染之前首先填充商店,而不是渲染“正在加載”組件,而是可以直接渲染“登錄”或“主頁”組件。

Verry的常見方法是對異步操作執行3個動作

types.js

export const FETCH_PROFILE_REQUEST = 'FETCH_PROFILE_REQUEST';
export const FETCH_PROFILE_SUCCESS = 'FETCH_PROFILE_SUCCESS';
export const FETCH_PROFILE_FAIL = 'FETCH_PROFILE_FAIL';

actions.js

import * as types from './types';

export function fetchProfile() {
  return dispatch => {
    dispatch({
      type: types.FETCH_PROFILE_REQUEST
    });
    AsyncStorage.getItem('@myapp:profile')
      .then((profileString) => {
        dispatch({
          type: types.FETCH_PROFILE_SUCCESS,
          data: profileString ? JSON.parse(profileString) :  {}
        });
      })
      .catch(error => {
        dispatch({
          type: types.FETCH_PROFILE_ERROR,
          error
        });
      });
  };
}

reducer.js

import {combineReducers} from 'redux';
import * as types from './types';

const isFetching = (state = false, action) => {
  switch (action.type) {
    case types.FETCH_PROFILE_REQUEST:
      return true;
    case types.FETCH_PROFILE_SUCCESS:
    case types.FETCH_PROFILE_FAIL:
      return false;
    default:
      return state;
  }
};

const data = (state = {}, action) => {
  switch (action.type) {
    case types.FETCH_PROFILE_SUCCESS:
      return action.data;
  }
  return state;
};

export default combineReducers({
  isFetching,
  data
});

這樣您就可以在組件中獲取isFetching道具並顯示/隱藏Loader組件

您可以在啟動屏幕中加載所有數據,然后再加載其他屏幕。 我是這樣做的。 希望能幫助到你

class Root extends Component {
    constructor(props) {
        super(props);
        this.state = {
            isLoading: true,
            store: configureStore( async () => {

                const user = this.state.store.getState().user || null;

                if (categories && categories.list.length < 1) {
                    this.state.store.dispatch(categoriesAction());
                }
                this.setState({
                    isLoading: false
                });

            }, initialState)
        };
    }


    render() {
        if (this.state.isLoading) {
            return <SplashScreen/>;
        }
        return (
            <Provider store={this.state.store}>
                <AppWithNavigationState />
            </Provider>
        );
    }
}

Redux和Redux Persist( https://github.com/rt2zz/redux-persist )將解決您的問題。 不要使它們復雜。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM