在任何Component渲染之前,React native + redux使用数据填充存储

时间:2016-08-30 08:09:20

标签: reactjs react-native redux react-redux

我很反应原生+ redux。我有一个反应原生应用程序,用户第一个屏幕登录,登录后显示服务器的类别列表页面。要获取需要传递身份验证令牌的类别列表,我们可以从登录屏幕获取,或者如果他先前从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的连接方法,我订阅了商店更改并有条件地加载登录页面。

 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);

所以首先&#39;正在加载&#39;组件得到渲染,当填充商店时,然后“登录”&#39;或者&#39; Home&#39;组件得到渲染。这是正确的流程吗?或者有一种方法可以在任何组件渲染之前首先填充商店,而不是渲染&#39;加载&#39;组件我可以直接呈现&#39;登录&#39;或者&#39; Home&#39;零件。

3 个答案:

答案 0 :(得分:1)

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 prop并显示/隐藏Loader组件

答案 1 :(得分:0)

您可以在启动画面中加载所有数据,然后加载其他屏幕。我是这样做的。希望它有所帮助

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>
        );
    }
}

答案 2 :(得分:0)

Redux和Redux Persist(https://github.com/rt2zz/redux-persist)将解决您的问题。 不要使它们复杂。

相关问题