React Redux服务器呈现但客户端获取数据

时间:2017-02-28 23:01:45

标签: reactjs redux react-router react-redux isomorphic-javascript

我正在我的演示反应应用程序上进行服务器渲染。虽然它可以工作,如果我刷新网址上的页面来获取医生像/ 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

1 个答案:

答案 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获取数据的好方法是什么?

处理异步操作的“老旧”方式是使用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