reactjs - 在反应中渲染之前获取数据的最佳位置
问题描述
我想知道在反应生命周期中我应该在哪里获取我的数据。我试图将我的数据放入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 定义了存储状态。希望有人能告诉我我做错了什么。谢谢!
解决方案
您可以在 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;
推荐阅读
- ios - 从情节提要添加的 tableview 上方的普通视图在运行的 iOS App 中不可见
- javascript - 即使变量具有值,Javascript 变量也不会附加到 HTML 元素
- ios - 如何在动作表样式的 UIAlertController 中有多个突出显示的颜色?
- firebase - 实时 Firebase 删除权限被拒绝
- sql - 将日期调整为列中的最小值
- angular - 如何使用 API 调用生命周期挂钩从服务器获取数据并且不影响其他服务
- spring-boot - Ftp 出站适配器 | 无法写入 ftp
- git - 如何使用jenkins在git中获取更改的文件列表
- c# - 排序嵌套列表和字典
- ios - 使用通知服务扩展振动 iphone 7,但它在后台无法与 iOS 12.1 一起使用