[英]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.