首页 > 解决方案 > 在反应中渲染之前获取数据的最佳位置

问题描述

我想知道在反应生命周期中我应该在哪里获取我的数据。我试图将我的数据放入componentDidMount()并且componenWillMount() 但没有成功......

componentWillMount(){
   
 // this fetch the data from back-end set a store state with the payload
        this.props.fetchUser(); 
        this.setState({userData:this.props.auth});
}

//fetchMethod
export const fetchUser = () => async dispatch =>{//using redux-thunk


    const res= await axios.get('/api/current_user')

    dispatch({type:FETCH_USER, payload:res.data}); 
    
    

};

在我的渲染函数中,我尝试通过调用来使用获取的 userData this.state.userData。但它是未定义的。我还尝试通过调用正确的商店状态来获取它,但也没有成功。我没有得到的是,根据我的 localstorage 定义了存储状态。希望有人能告诉我我做错了什么。谢谢!

标签: reactjsredux

解决方案


您可以在 componentWillMount 或 componentDidMount 生命周期方法中进行获取(需要注意的是,当您有一个服务器呈现的应用程序时,如果您在 componentWillMount 中发出请求,您将遇到同步服务器呈现的 html 和重新水化的 html 的问题。)

this.state.userData 未定义的原因是因为对数据的调用本质上是异步的。我建议向您的组件添加功能以检查是否正在进行 api 调用(isLoading也许?),以及它是否已完成(isLoaded也许?)。

connect react-redux在实现方面,假设您使用高阶组件,它会是这样的:

class YourComponent extends React.Component {

  componentDidMount() {
    this.props.fetchUser();
  }

  render() {
    const { isLoading, isLoaded, data } = this.props;
    if (isLoading) return <Loader />; // Or whatever you want to return when it is loading
    if (!isLoaded || !data) return null; // If it is not loading and its not loaded, then return nothing.
    return (
      <div>
        <h1>{data.name}</h1>
        <h2>{data.id}</h2>
      </div>
    )
  }

}

const mapStateToProps = state => ({
  isLoading: state.user.isLoading,
  isLoaded: state.user.isLoaded,
  userData: state.user.data
});

export default connect(mapStateToProps, { fetchUser })(YourComponent);

在您的动作调度程序/中间件中,您需要考虑异步调用的开始。假设这是用 redux thunk 之类的东西来解释的......

const initialState = {
  isLoaded: false,
  isLoading: false,
  data: {},
}

const reducer = (state = initialState, action) => {
  switch (action.type) {
    case FETCH_USER:
      return {
        ...state,
        isLoading: true,
      }
    case FETCH_USER_SUCCESS:
      return {
        isLoading: false,
        isLoaded: true,
        data: action.payload
      };
    default:
      return state;
  }
};

export default reducer;

推荐阅读