首页 > 解决方案 > 在更新状态之前需要调用两次 Redux 操作?

问题描述

我正在调用一个 redux 操作,它向数据库发出 get 请求并返回一个包含正确数据的对象。我已经通过系统跟踪对象,显示它一直正确发送到反应组件,但是,当调用 redux 操作时,对象没有得到更新。如果进行第二次调用,则更新状态。我认为这与异步行为有关,但我不确定如何解决它。

以下是调用该操作的组件的相关部分:

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { MDBContainer, MDBInput, MDBBtn } from 'mdbreact';
import { getSinglePatient } from '../../../actions/patientActions';
import PatientConfirmModal from '../../modals/PatientConfirmModal';

export class SelectPatient extends Component {
    state = {
        patientConfirmModalToggle: false,
        patient: {},
        searchID: ''
    };

    static propTypes = {
        patient: PropTypes.object.isRequired,
        getSinglePatient: PropTypes.func.isRequired
    };

    onChange = e => {
        this.setState({ [e.target.name]: e.target.value });
    };

    toggleConfirmModal = () => {
        this.setState({
            patientConfirmModalToggle: !this.state.patientConfirmModalToggle
        });
    };


    searchForPatient = () => {
        this.props.dispatch(getSinglePatient(this.state.searchID)); // edit 1
        console.log(this.props.patient);
        const newPatient = this.props.patient.patients[0];

        console.log(newPatient);
        if (newPatient !== undefined) {
            this.setState({
                patient: newPatient
            });
            this.toggleConfirmModal();
        }
        console.log(this.state.patient);
    };

    render() {
        return (
            <MDBContainer>
                <h3>Please enter a Patient ID to begin an assessment</h3>
                <MDBInput
                    label="Patient ID"
                    group
                    type="text"
                    name="searchID"
                    id="searchID"
                    onChange={this.onChange}
                />
                <MDBBtn
                    onClick={() => this.searchForPatient()}
                >
                    Search
                </MDBBtn>
                <PatientConfirmModal
                    modal={this.state.patientConfirmModalToggle}
                    patient={this.state.patient}
                    toggle={this.toggleConfirmModal}
                />
            </MDBContainer>
        );
    }
}

function mapStateToProps(state){
    console.log(state)
    return{
        patient: state.patient
    }
}

export default  connect(mapStateToProps , {getSinglePatient})(SelectPatient);

这是动作本身:

export const getSinglePatient = id => (dispatch, getState) => {
    dispatch(setPatientsLoading());
    axios
        .get(`/api/patients/${id}`, tokenConfig(getState))
        .then(res =>
            dispatch({
                type: GET_SINGLE_PATIENT,
                payload: res.data[0]
            })
        )
        .catch(err =>
            dispatch(returnErrors(err.response.data, err.response.status))
        );
};

这是它被发送到的路线:

// @route   GET api/patients
// @desc    Get a single patient
// @access  Public
router.get('/:id', (req, res) => {
    console.log('GET single request hit (ID:' + req.params.id + ')');
    Patient.find({ patientID: req.params.id }).then(patient => {
        res.json(patient);
    });
});

以下是控制台日志的结果(按一次搜索按钮的第一个结果,再次按一次并再次调用该操作的第二个结果):

编辑:来自下面建议的代码的更新错误(患者已切换到客户端,但这对代码没有影响,因为它已被完全重构)

结果: 结果

标签: javascriptreactjsreduxmdbreact

解决方案


    //make sure you are dispatching your action like below
   // this.props.dispatch(your_action())
     
     searchForPatient = () => {
        this.props.dispatch(getSinglePatient(this.state.searchID)); //make change
        console.log(this.props.patient);
        const newPatient = this.props.patient.patients[0];

        console.log(newPatient);
        if (newPatient !== undefined) {
            this.setState({
                patient: newPatient
            });
            this.toggleConfirmModal();
        }
        console.log(this.state.patient);
    }
   
     
    //use mapStateToProps function  to access your resultent data comes from server : you can get your result in this.props
   //put this funcion above export default co.... 
   function mapStateToProps(state){
        console.log(state)
        return{
            patient : state.patient
        }
    }


    export default  connect(mapStateToProps , {getSinglePatient} )(SelectPatient)

推荐阅读