简体   繁体   中英

Dispatch a Redux action from a modal in React

I'm a begginer in React and I'm trying to find a way to dispatch a redux action from a modal.

I have a list of products and a button 'add to bag' under each image. When we click on the button 'add to bag', I want a modal to appear that ask for a confirmation. The action need to be dispatched when the user click on the confirm button inside de modal window.

The action need to grab the item object.

All is working fine...but I'm not able to pass the item into the action when I want to launch the action from the modal.

So, my problem is not the Redux side but the modal part ( I use React-bootstrap for the modal).

I have this error message: 'item' is not defined

I'm not sure I understand exactly why this does'nt work and I failed to find a solution. I tried so many things but it's just not working.

Is there a simple way to add/pass the item data into the modal easily?

Help would be very appreciated: :)

Thanks a lot !!!

Here are part of my files:

Product.js

import { Modal } from "react-bootstrap";

function Products(props) {
  const [show, setShow] = useState(false);

  const handleClose = () => setShow(false);
  const handleShow = () => setShow(true);

  return (
    <div>
      <CardGroup>
        {_.map(props.data, (item) => (
          <Col>
           ...Some code here
                <div>
                  <div>
                    {item.name.map((item) => (
                      <ul key={item}>{item}</ul>
                    ))}
                  </div>

              <div>
                <button onClick={() => {handleShow()}}>
                  Add to bag
                </button>
              </div>
            </div>
          </Col>
        ))}
      </CardGroup>

      <Modal show={show} onHide={handleClose}>
        <Modal.Body>Please confirm you want to add this product</Modal.Body>
        <Modal.Footer>
          <button
            onClick={props.addProductToBasket(item)}
          >
            Confirm
          </button>
          <button onClick={handleClose}>Cancel</button>
        </Modal.Footer>
      </Modal>
    </div>
  );
}

const mapStateToProps = (state) => {
  return { code here ...};
};

const mapDispatchToProps = (dispatch) => {
  return {
    addProductToBasket: (id) => dispatch(addProductToBasket(id)),
  };
};

export default connect(mapStateToProps, mapDispatchToProps)(Products);

Here is the part of my Product.js file im my Store/actions folder

export const addProductToBasket = (id) => {
    
  return {
    type: ADD_PRODUCTD_TO_BASKET,
    payload: id,
  };
};

Since you only show the modal if an item was clicked, store the item or null instead of Boolean in the state, and open and close the modal accordingly:

function Products(props) {
  const [selectedItem, setShowItem] = useState(null); // item for open model or null for closed

  const handleClose = () => setShowItem(null);
  const handleShow = item => setShowItem(item);

  return (
    <div>
      <CardGroup>
        {_.map(props.data, (item) => (
          <Col>
           ...Some code here
                <div>
                  <div>
                    {item.name.map((item) => (
                      <ul key={item}>{item}</ul>
                    ))}
                  </div>

              <div>
                <button onClick={() => handleShow(item)}>
                  Add to bag
                </button>
              </div>
            </div>
          </Col>
        ))}
      </CardGroup>

      <Modal show={selectedItem !== null} onHide={handleClose}>
        <Modal.Body>Please confirm you want to add this product</Modal.Body>
        <Modal.Footer>
          <button
            onClick={() => props.addProductToBasket(selectedItem)}
          >
            Confirm
          </button>
          <button onClick={handleClose}>Cancel</button>
        </Modal.Footer>
      </Modal>
    </div>
  );
}

Not related, but it will make your life easier - use the object form of mapDispatchToProps that will save you the need to wrap with dispatch manually:

const mapDispatchToProps = {
  addProductToBasket
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM