Home > Back-end >  Pass props between siblings in React
Pass props between siblings in React

Time:07-22

I'm passing a prop containing an array of objects down to a child component where it's mapped and each object is displayed. One of the keys of each object is name. On each of these newly displayed objects, a clickable image is also rendered and can be pressed which displays a modal with some text. I want the text to dynamically include the same name prop as the mapped object.

I figure I'd need to pass it as a state to the parent, and then back down to the modal?

The prop is passed from the top-level parent to the WarehouseListItems component:

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

  const toggleShow = () => {
    setShow((state) => !state);
  };
  return (
    <section>
          <WarehouseListItems
            warehouseData={props.warehouseData}
            toggleShow={toggleShow}
          />
          <DeleteWarehouseModal
            onClose={() => setShow(false)}
            show={show}
          />
    </section>
  );
}

Then, each object is mapped and passed to the WarehouseListItem component:

function WarehouseListItems(props) {
  const { toggleShow } = props;
  let items = props.warehouseData;
  return (
    <>
      {items.map((item) => {
        return <WarehouseListItem item={item} toggleShow={toggleShow} />;
      })}
    </>
  );
}

Then, the object is rendered, including the name key from the passed prop:

function WarehouseListItem(props) {
  const { toggleShow } = props;

  return (
    <div>
      <div>
        <div>
          <div>WAREHOUSE</div>
          <Link to={`/warehouses/${props.item.name}`}>
            <div>
              {props.item.name}
            </div>
          </Link>
        </div>
        <Link>
          <div
            onClick={() => toggleShow()}
          ></div>
        </Link>
      </div>
    </div>
  );
}

How can I pass the same data from props.item.name to my modal component?

const DeleteWarehouseModal = (props) => {
  if (!props.show) {
    return null;
  }
  return (
    <div>
      <div>
        <div>
          <div>
            <img
              src={closeIcon}
              alt="Close pop-up icon"
              onClick={props.onClose}
            ></img>
            <h3>
              Delete [DYNAMIC] warehouse?
            </h3>
          </div>
          <div>
            <p>
              {`Please confirm that you’d like to delete the [DYNAMIC] from the list
            of warehouses. You won’t be able to undo this action.`}
            </p>
          </div>
          <div>
            <button
              onClick={props.onClose}
            >
              Cancel
            </button>
            <button>Delete</button>
          </div>
        </div>
      </div>
    </div>
  );
};

CodePudding user response:

Instead of a boolean "show" state, you can have the "show" state instead be an item in the WarehouseList component that represents the "active" item that might be deleted:

function WarehouseList(props) {
  const [itemToDelete, setItemToDelete] = useState(null);

  return (
    <section>
          <WarehouseListItems
            warehouseData={props.warehouseData}
            setItemToDelete={(item) => setItemToDelete(item)}
          />
          {itemToDelete !== null && <DeleteWarehouseModal
            item={itemToDelete}
            onClose={() => setItemToDelete(null)}
          />}
    </section>
  );
function WarehouseListItems(props) {
  const { setItemToDelete } = props;
  let items = props.warehouseData;
  return (
    <>
      {items.map((item) => {
        return <WarehouseListItem item={item} setItemToDelete={setItemToDelete} />;
      })}
    </>
  );
}
function WarehouseListItem(props) {
  const { setItemToDelete } = props;

  return (
    <div>
      <div>
        <div>
          <div>WAREHOUSE</div>
          <Link to={`/warehouses/${props.item.name}`}>
            <div>
              {props.item.name}
            </div>
          </Link>
        </div>
        <Link>
          <div
            onClick={() => setItemToDelete(props.item)}
          ></div>
        </Link>
      </div>
    </div>
  );
}
const DeleteWarehouseModal = (props) => {
  const { item } = props;

  return (
    <div>
      <div>
        <div>
          <div>
            <img
              src={closeIcon}
              alt="Close pop-up icon"
              onClick={props.onClose}
            ></img>
            <h3>
              Delete {item.name} warehouse?
            </h3>
          </div>
          <div>
            <p>
              {`Please confirm that you’d like to delete the ${item.name} from the list
            of warehouses. You won’t be able to undo this action.`}
            </p>
          </div>
          <div>
            <button
              onClick={props.onClose}
            >
              Cancel
            </button>
            <button>Delete</button>
          </div>
        </div>
      </div>
    </div>
  );
};
  • Related