Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/webpack/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 反应本机+;在任何组件渲染之前,用数据填充存储_Reactjs_React Native_Redux_React Redux - Fatal编程技术网

Reactjs 反应本机+;在任何组件渲染之前,用数据填充存储

Reactjs 反应本机+;在任何组件渲染之前,用数据填充存储,reactjs,react-native,redux,react-redux,Reactjs,React Native,Redux,React Redux,我是一个新的反应原生+redux。我有一个react本机应用程序,其中用户的第一个屏幕是登录,登录后显示来自服务器的类别列表页面。要获取类别列表,需要传递身份验证令牌,我们可以从登录屏幕获取身份验证令牌,或者如果他以前登录过,则从异步存储获取身份验证令牌 因此,在重新设计任何组件之前,我将创建存储并手动分派fetchProfile()操作,如下所示 const store = createStore(reducer); store.dispatch(fetchProfile()); 因此,fe

我是一个新的反应原生+redux。我有一个react本机应用程序,其中用户的第一个屏幕是登录,登录后显示来自服务器的类别列表页面。要获取类别列表,需要传递身份验证令牌,我们可以从登录屏幕获取身份验证令牌,或者如果他以前登录过,则从异步存储获取身份验证令牌

因此,在重新设计任何组件之前,我将创建存储并手动分派fetchProfile()操作,如下所示

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
组件。所以你选择了正确的方法。我只是稍微重构了一下你的代码。