从父

时间:2017-08-01 08:08:16

标签: reactjs react-redux

parent component会调度要检索的操作以及删除项目。 子组件包含项目列表,并包含删除按钮。

这是我对事件顺序的计划

**Retrieve Address List:** 
Parent fetches list > Pass to Child > Display in Child <br> [ ->✓ Works well]

**Delete and Address** 
Child invokes delete action > Action dispatched via parent > Result received in parent > Result sent to child via props > Child re-renders <br> [ -> ✘ Object is deleted in server but component desn't re-render]

据我所知,事件序列应最终更新组件状态,强制重新呈现它。我错过了什么?

Parent Component

class Parent extends React.Component
{
    componentWillMount()
    {
        store.dispatch(fetchShippingAddresses());
    }

    deleteAddress(address_id)
    {
        store.dispatch(deleteShippingAddress(address_id));
    }

    render()
    {
      let shippingAddresses = this.props.shippingAddressesList;
      let deleteShippingAddressData = this.props.deleteShippingAddressData;

      return (

         <AddressList 
             shippingAddresses={shippingAddresses}
             deleteAddresses ={(address_id) => this.deleteAddress(address_id)}
             deleteShippingAddressData: this.props.deleteShippingAddressData

      )
    }

}

function mapStateToProps(state)
{
    return {
        shippingAddressesList : state.shippingAddressesList,
        deleteShippingAddressData : state.deleteShippingAddressData
    }
}

export default connect(mapStateToProps)(DashboardBody);

Child Component

class AddressList extends React.Component
{
  constructor(props)
    {
        super(props);
        this.state =
        {
            shippingAddresses: [],
            deleteShippingAddressData: {}
        }
    }

    componentWillReceiveProps(nextProps)
    {
        this.state.shippingAddresses !== nextProps.shippingAddresses &&
            this.setState({ shippingAddresses: nextProps.shippingAddresses });

        this.state.deleteShippingAddressData !==  nextProps.deleteShippingAddressData &&
        this.setState({ deleteShippingAddressData: nextProps.deleteShippingAddressData});
    }

    render()
    {
      addresses = this.state.shippingAddresses;
      return (

       <div >
            { addresses && addresses.data.map( (address, i) =>

                <p key={i}>
                  {address.address_name}
                  <button onClick={ event => this.props.deleteAddress(address.id) }>
                    Delete
                  </button>
                </p>

            )}
       </div>

     )
    }
}

Delete Action

import axios from 'axios';

export function deleteShippingAddress(address_id)
{
    return function(dispatch)
    {
        dispatch(destroyShippingAddressSuccess(false));
        dispatch(destroyShippingAddressError(null));

        const request = axios
        ({
            url: `http://api.stagingapp.io/location/v1/shipping/address/${address_id}`,
            method: "delete",
            dataType: 'json',
            headers: {
                'Content-Type': 'application/json',
                'Accept': 'application/json',
                'Authorization': 'Bearer ' + localStorage.getItem('access_token') }
        })

        .then(function(response)
        {
            destroyShippingAddressSuccess(response);
        })
        .catch(function(error)
        {
            dispatch(destroyShippingAddressError(error));
            console.log(error)
        });

        return { type: 'DESTROY_SHIPPING_ADDRESS_SUCCESS', payload: request }

    };

}

function destroyShippingAddressSuccess(deleteShippingAddressData)
{
    return {  type: 'DESTROY_SHIPPING_ADDRESS_SUCCESS', deleteShippingAddressData};
}
function destroyShippingAddressError(deleteShippingAddressError)
{
    return {  type: 'DESTROY_SHIPPING_ADDRESS_ERROR', deleteShippingAddressError };
}

export default deleteShippingAddress;

Deletion Reducer

export default function deleteShippingAddressReducer
    (state = { deleteShippingAddressError:'', deleteShippingAddressData:'' }, action)

        {
            switch (action.type)
            {
                case 'DESTROY_SHIPPING_ADDRESS_SUCCESS':
                    return Object.assign({}, state, { deleteShippingAddressData: action.deleteShippingAddressData});

                case 'DESTROY_SHIPPING_ADDRESS_ERROR':
                    return Object.assign({}, state, { deleteShippingAddressError: action.deleteShippingAddressError });

                default: return state;
            }
        }
    //
//

1 个答案:

答案 0 :(得分:0)

在您的reducer中,您使用的是action.deleteShippingAddress,但在您的动作创建器中,您正在使用destroyShippingAddressData创建一个对象。重命名它以匹配reducer或action,具体取决于您要保留的名称。