我正在我的演示反应应用程序上进行服务器渲染。虽然它可以工作,如果我刷新网址上的页面来获取医生像/ doctor /:id如果我在/登录并尝试去/ 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)));
};
}
LOG ERROR
TypeError: Cannot read property 'name' of undefined
答案 0 :(得分:1)
用户友好的方法是在没有医生可用的情况下进入页面/doctor/123456
,以便用户立即得到他的行动(导航到第x页)的反馈。在onEnter
react-routers方法或componentDidMount
中,您应该启动一个操作fetchDoctor
,同时向用户显示一个微调器或一条消息,指示正在加载数据。
render() {
return (
<div>
{ this.props.doctor && <div>{this.props.doctor.name.first}</div> }
{ ! this.props.doctor && <YourSpinnerComponent/> }
</div>
);
}
因此,上面的渲染方法在加载数据时会显示一些内容,当数据进入时,它会显示它而没有任何错误。
处理异步操作的“老旧”方式是使用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