调用PUT方法Api后如何重新渲染?

时间:2019-10-18 15:15:04

标签: reactjs redux

商店的更新进行得很顺利,但是更改仅在刷新页面后出现。这是我的减速器:

export default function (state = initialState, action) {
    switch (action.type) {
        case GET_SHIPMENTS:
            return {
                ...state,
                shipments: action.payload
            };
        case GET_SHIPMENTS_BY_BIKER:
            return {
                ...state,
                shipments: action.payload
            };
        case GET_SHIPMENT:
            return {
                ...state,
                shipment: action.payload
            };
        case UPDATE_SHIPMENT:
            return {
                ...state,
                shipment: action.payload
            };
        default:
            return state;
    }
}

这是我的动作

export const updateShipment = (id, shipmentData) => dispatch => {
    const requestOption = {
        method: 'PUT',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify(shipmentData)
    };

    fetch('http://localhost:3002/api/shipments/' + id, requestOption)
        .then(res => res.json())
        .then(shipment =>
            dispatch({
                type: UPDATE_SHIPMENT,
                payload: shipment
            })
        )
        .catch(err => {
            console.log(err);
        });
};

这是react组件,它首先获取所有需要的对象,更新之后,我希望获取所有需要的对象,只需进行修改

class BikerToDo extends Component {
    state = {
        biker_id: 1,
        shipment_id: this.props.shipment.id,
        origin: this.props.shipment.origin,
        destination: this.props.shipment.destination,
        order_status: '',
        pickUp_time: this.props.shipment.pickUp_time,
        delivery_time: this.props.shipment.delivery_time,
        id_button_show: 0
    };

    UNSAFE_componentWillMount() {
        this.props.getShipmentsByBiker(this.state.biker_id);
    }

    componentDidMount() {
        this.props.getBikers();
    }

    componentWillReceiveProps(nextProps) {
        if (nextProps.shipment) {
            this.setState({
                shipment_id: nextProps.shipment.id,
                origin: nextProps.shipment.origin,
                destination: nextProps.shipment.destination,
                pickUp_time: nextProps.shipment.pickUp_time,
                delivery_time: nextProps.shipment.delivery_time,
            });
        }
    };

    handleChange = (e) => {
        const {name, value} = e.target;
        this.setState({
            [name]: value,
            id_button_show: 0
        }, () => this.props.getShipmentsByBiker(this.state.biker_id));
    };

    handleStatusChanger = (e, id) => {
        const {name, value} = e.target;
        this.setState({
            [name]: value,
            id_button_show: id
        });
    };

    handleShipment = id => {
        this.props.getShipment(id);
    };

    handleUpdate = () => {
        const id = this.state.shipment_id;
        const shipment = {
            origin: this.state.origin,
            destination: this.state.destination,
            assignee: this.state.biker_id,
            order_status: this.state.order_status,
            pickUp_time: this.state.pickUp_time,
            delivery_time: this.state.delivery_time,
        };

        this.props.updateShipment(id, shipment);

        this.setState({
            id_button_show: 0
        });

    };

    render() {
        const shipmentsByBiker = this.props.shipments.map(shipment => (
            <tbody>
            <tr onClick={() => this.handleShipment(shipment.id)}>
                <td>{shipment.id}</td>
                <td>{shipment.origin}</td>
                <td>{shipment.destination}</td>
                <td><Form.Control as={"select"} name={"order_status"} onChange={e => this.handleStatusChanger(e, shipment.id)}>
                    <option value={"ASSIGNED"} key={"ASSIGNED"}
                            selected={shipment.order_status === "ASSIGNED"}>Choose Action
                    </option>
                    <option value={"PICKED_UP"} key={"PICKED_UP"}
                            selected={shipment.order_status === "PICKED_UP"}>PICKED UP
                    </option>
                    <option value={"DELIVERED"} key={"DELIVERED"}
                            selected={shipment.order_status === "DELIVERED"}>DELIVERED
                    </option>
                </Form.Control></td>
                <td style={{ width: "20%" }}>{shipment.pickUp_time}</td>
                <td style={{ width: "20%" }}>{shipment.delivery_time}</td>
                <td>{shipment.id === this.state.id_button_show &&
                <Button type={"submit"} value={"Edit"} onClick={this.handleUpdate}>Edit</Button>}</td>
            </tr>
            </tbody>
        ));
        return (
            <div>
                <Nav.Link as={Link} to={'/'}>Manager's Dashboard</Nav.Link>
                <h1>To Do</h1>
                <Form.Control as={"select"} name={"biker_id"}
                              onChange={(e) => this.handleChange(e)}>
                    {this.props.bikers.map(biker => (
                        <option value={biker.id} key={biker.id}
                                selected={this.state.id == biker.id}>{biker.name}</option>
                    ))
                    }
                </Form.Control>
                <br/><br/>
                <Table responsive striped bordered hover variant="dark">
                    <thead>
                    <tr>
                        <th>ID</th>
                        <th>Origin</th>
                        <th>Destination</th>
                        <th>Order Status</th>
                        <th>Pick Up Time</th>
                        <th>Delivery Time</th>
                        <th></th>
                    </tr>
                    </thead>
                    {shipmentsByBiker}
                </Table>
            </div>
        );
    }
}

BikerToDo.propTypes = {
    getShipmentsByBiker: PropTypes.func.isRequired,
    getBikers: PropTypes.func.isRequired,
    getShipment: PropTypes.func.isRequired,
    shipments: PropTypes.array.isRequired,
    bikers: PropTypes.array.isRequired,
    shipment: PropTypes.object.isRequired,
    updateShipment: PropTypes.func.isRequired,
};

const mapStateToProps = state => ({
    shipments: state.shipments.shipments,
    bikers: state.bikers.bikers,
    shipment: state.shipments.shipment
});

export default connect(mapStateToProps, {getShipmentsByBiker, getBikers, getShipment, updateShipment})(BikerToDo);

我试图在更新后立即调用GET方法Api,但是什么也没发生。

2 个答案:

答案 0 :(得分:1)

我认为问题与咖喱调度功能有关

export const updateShipment = (id, shipmentData) => dispatch => {

通常,咖喱函数将返回一些要传递的值。咖喱函数中的异步(获取)似乎会导致某种竞争状况。我敢打赌这会干扰调度。

Reddit api示例redux文档:

function fetchPosts(subreddit) {
  return dispatch => {
    dispatch(requestPosts(subreddit))
    return fetch(`https://www.reddit.com/r/${subreddit}.json`)
      .then(response => response.json())
      .then(json => dispatch(receivePosts(subreddit, json)))
  }
}

https://bugs.llvm.org/show_bug.cgi?id=43714

答案 1 :(得分:0)

  • 您没有正确设置减速器。你应该遍历 获取/修补单身时的货运阵列
  • 在化简器中具有嵌套状态是一种反模式,即使 状态已正确迭代。
  • 请记住,获取,更新和创建单个货件 关于还原状态,通常是同一回事,您可以在以下情况下重新使用GET_SHIPMENT:修补,发布或获取单批货
  • 如果您需要与常规运输分开跟踪摩托车运输 在状态下使用单独的减速器

尝试这样的事情:

export default function (state = initialState, action) {
    switch (action.type) {
        case GET_SHIPMENTS:
            return action.payload;
        case GET_SHIPMENTS_BY_BIKER: //if you need to track biker shipments separate from regular shipments in state use a separate reducer
            return action.payload; 
        case GET_SHIPMENT:
            let shipmentFound = false
            const newState = state.map(shipment=>{
                if(shipment.id === action.payload.id){
                    shipmentFound = true
                    return action.payload
                }
                return shipment
            })
            return shipmentFound ? newState : [...newState, action.payload]

        case UPDATE_SHIPMENT: 
                let shipmentFound = false
                const newState = state.map(shipment=>{
                    if(shipment.id === action.payload.id){
                        shipmentFound = true
                        return action.payload
                    }
                    return shipment
                })
                return shipmentFound ? newState : [...newState, action.payload]
            default:
                return state;
        }
    }

然后在您的mapStateToProps

const mapStateToProps = state => ({
    shipments: state.shipments,
    bikers: state.bikers.bikers
});

访问一次货运:

const someShipment = this.props.shipments.find(shipment=> shipment.id === 'someID')

(您可能还需要从外观上更新您的机车减速器)