Reactjs 反应本机+;在任何组件渲染之前,用数据填充存储
我是一个新的反应原生+redux。我有一个react本机应用程序,其中用户的第一个屏幕是登录,登录后显示来自服务器的类别列表页面。要获取类别列表,需要传递身份验证令牌,我们可以从登录屏幕获取身份验证令牌,或者如果他以前登录过,则从异步存储获取身份验证令牌 因此,在重新设计任何组件之前,我将创建存储并手动分派fetchProfile()操作,如下所示Reactjs 反应本机+;在任何组件渲染之前,用数据填充存储,reactjs,react-native,redux,react-redux,Reactjs,React Native,Redux,React Redux,我是一个新的反应原生+redux。我有一个react本机应用程序,其中用户的第一个屏幕是登录,登录后显示来自服务器的类别列表页面。要获取类别列表,需要传递身份验证令牌,我们可以从登录屏幕获取身份验证令牌,或者如果他以前登录过,则从异步存储获取身份验证令牌 因此,在重新设计任何组件之前,我将创建存储并手动分派fetchProfile()操作,如下所示 const store = createStore(reducer); store.dispatch(fetchProfile()); 因此,fe
const store = createStore(reducer);
store.dispatch(fetchProfile());
因此,fetchProfile()尝试从异步存储中读取配置文件数据,并使用数据分派操作
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);
MyApp类扩展了React.Component{
render(){
如果(此.props.profile)
if(此.props.profile.authentication\u令牌)
retunr();
其他的
返回();
其他的
返回();
}
}
从'react redux'导入{connect};
常量mapStateToProps=(状态)=>{
返回{
profile:state.profile
}
}
module.exports=connect(mapStateToProps,null)(MyApp);
所以,首先“加载”组件被渲染,当存储区被填充时,“登录”或“主”组件被渲染。那么这是一个正确的流程吗?或者有没有一种方法可以让我在任何组件渲染之前先填充存储区,而不是渲染“加载”组件,我可以直接渲染“登录”或“主”组件 非常常见的方法是对异步操作有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';
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
});
});
};
}
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
});
actions.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';
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
});
});
};
}
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
});
reducer.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';
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
});
});
};
}
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,并显示/隐藏加载程序组件非常常见的方法是为异步操作提供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';
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
});
});
};
}
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
});
actions.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';
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
});
});
};
}
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
});
reducer.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';
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
});
});
};
}
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并显示/隐藏加载程序组件您可以在启动屏幕期间加载所有数据,然后加载其他屏幕。我是这样做的。希望能有帮助
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>
);
}
}
类根扩展组件{
建造师(道具){
超级(道具);
此.state={
孤岛加载:是的,
存储:配置存储(异步()=>{
const user=this.state.store.getState().user | | null;
if(categories&&categories.list.length<1){
this.state.store.dispatch(categoriesAction());
}
这是我的国家({
孤岛加载:false
});
},初始状态)
};
}
render(){
if(此.state.isLoading){
返回;
}
返回(
);
}
}
您可以在启动屏幕期间加载所有数据,然后加载其他屏幕。我是这样做的。希望能有帮助
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>
);
}
}
类根扩展组件{
建造师(道具){
超级(道具);
此.state={
孤岛加载:是的,
存储:配置存储(异步()=>{
const user=this.state.store.getState().user | | null;
if(categories&&categories.list.length<1){
this.state.store.dispatch(categoriesAction());
}
这是我的国家({
孤岛加载:false
});
},初始状态)
};
}
render(){
if(此.state.isLoading){
返回;
}
返回(
);
}
}
Redux和Redux Persist()将解决您的问题。
不要把它们复杂化 Redux和Redux Persist()将解决您的问题。
不要把它们复杂化 上面问题中的代码也在做同样的事情,但我只是想确认一下,我的方法是否正确?因为商店在渲染后会被填充。所以呈现首先发生(直到加载组件),然后存储区由fetchProfile填充,这将触发重新呈现,然后进入登录或主页。因此,在任何组件呈现之前,都可以从AsyncStorage中预填充存储数据。这是可能的,但之后您将向用户显示一个空白屏幕。如果您有一个异步操作,通常最好让用户知道应用正在加载并显示
Loader
组件。所以你选择了正确的方法。我只是对你们的代码进行了一点重构。上面问题中的代码也在做同样的事情,但我只是想确认一下,我做得对吗?因为商店在渲染后会被填充。所以呈现首先发生(直到加载组件),然后存储区由fetchProfile填充,这将触发重新呈现,然后进入登录或主页。因此,在任何组件呈现之前,都可以从AsyncStorage中预填充存储数据。这是可能的,但之后您将向用户显示一个空白屏幕。如果您有一个异步操作,通常最好让用户知道应用正在加载并显示Loader
组件。所以你选择了正确的方法。我只是稍微重构了一下你的代码。