React Redux 服务器渲染但客户端获取数据
Posted
技术标签:
【中文标题】React Redux 服务器渲染但客户端获取数据【英文标题】:React Redux server render but client side fetch data 【发布时间】:2017-07-20 02:37:54 【问题描述】:我正在我的一个演示反应应用程序上进行服务器渲染。尽管如果我刷新 url 上的页面以获取像 /doctor/:id 这样的医生,如果我在 /login 并尝试转到 /doctor/123456 ,但医生属性为空并且(this.props.doctor.name .first) 失败。
在这些情况下使用 redux 获取数据的好方法是什么?
代码如下
import fetchDoctor from '../../DoctorActions';
import getDoctor from '../../DoctorReducer';
class DoctorDetailPage extends Component
render()
return (
<div>this.props.doctor.name.first</div>
);
DoctorDetailPage.need = [params =>
return this.props.dispatch(fetchDoctor(params.id));
];
function mapStateToProps(state, props)
return
doctor: getDoctor(state, props.params.id),
;
DoctorDetailPage.propTypes =
doctor: PropTypes.shape(
insurance: PropTypes.string,
description: PropTypes.string,
GUID: PropTypes.string,
name: PropTypes.shape(
first: PropTypes.string,
last: PropTypes.string,
)
),
dispatch: PropTypes.func.isRequired,
;
export default connect(mapStateToProps)(DoctorDetailPage);
减速器
import ADD_DOCTOR from './DoctorActions';
// Initial State
const initialState = list: [] ;
const DoctorReducer = (state = initialState, action = ) =>
switch (action.type)
case ADD_DOCTOR:
return
list: [action.doctor, ...state.list],
;
default:
return state;
;
export const getDoctor = (state, id) =>
return state.doctors.list.filter(doctor => doctor._id === id)[0];
;
export default DoctorReducer;
动作
import callApi from '../../util/apiCaller';
// Export Constants
export const ADD_DOCTOR = 'ADD_DOCTOR';
// Export Actions
export function addDoctor(doctor)
return
type: ADD_DOCTOR,
doctor,
;
export function addDoctorRequest()
return () =>
return true;
;
export function fetchDoctor(id)
return (dispatch) =>
return callApi(`doctors/$id`)
.then(res => dispatch(addDoctor(res)));
;
日志错误
TypeError: Cannot read property 'name' of undefined
【问题讨论】:
控制台显示的错误是什么? “类型错误:无法读取未定义的属性‘名称’”,因为医生未定义。尽管服务器端正在工作,但在客户端获取失败 您能否切换到“网络”选项卡并告诉我们 API 调用是否在客户端正确进行? 不,不是。这就像在解析该对象之前尝试渲染。解决它的唯一方法是让 componentDidMount 函数和医生的 setState 清空。这种方式可以将其显示为空,然后将其替换为获取的数据。但这不是 redux 的做法 【参考方案1】:一般来说,获取数据的好方法是什么?
一种用户友好的方法是进入页面/doctor/123456
而不需要有医生,这样用户就会得到即时反馈,表明他的操作(导航到第 x 页)有效。在 react-router 的 onEnter
方法或 componentDidMount
中,您应该启动一个操作 fetchDoctor
并同时向用户显示一个微调器或一条指示正在加载数据的消息。
render()
return (
<div>
this.props.doctor && <div>this.props.doctor.name.first</div>
! this.props.doctor && <YourSpinnerComponent/>
</div>
);
所以上面的渲染方法在加载数据时显示了一些东西,当数据进来时它显示它没有任何错误。
使用 redux 获取数据的好方法是什么?
处理异步操作的“古老”方式是使用redux-thunk
。你可以阅读这个great SO answer about dispatching asynchronous redux actions。
最新趋势是使用redux-saga
。它是一个旨在使 React/Redux 应用程序中的副作用(即数据获取之类的异步操作和访问浏览器缓存之类的不纯操作)更容易和更好的库。 More about redux-saga
.
因此,在您的情况下,您将创建一个 Saga 来处理获取。
More about redux-thunk
vs redux-saga
in this great SO answer.
【讨论】:
感谢您的回答,效果很好。只是为了让其他用户知道,如果您将 return () 放在像 .. return (Hello!
this.props.doctor && this.props.doctor.name.first ); @PanagiotisVrs 感谢您的注意。我也更正了答案。以上是关于React Redux 服务器渲染但客户端获取数据的主要内容,如果未能解决你的问题,请参考以下文章
react + redux + saga +服务器端渲染+如何停止服务器端渲染页面的额外ajax调用?