【问题标题】:setting url query for modal为modal设置url查询
【发布时间】:2020-08-05 07:25:40
【问题描述】:

我正在使用图像搜索和显示应用程序。用户可以单击照片,然后会弹出一个模式。那些模态将在 url 中有id。但是,当我刷新页面时,模式不存在并且显示错误。我从 unsplash api 获取 url,所以随着页面刷新重新加载,url 消失了。如何将 url 保留在 url 查询中,以便即使在页面刷新时 url 仍然存在?

网站

import React, { useState } from "react";
import { Link, BrowserRouter as Router, Route } from "react-router-dom";
import ModalWrapper from "./ModalWrapper";

const ListItem = ({ photo }) => {
  return (
    <>
      <Router>
        <div key={photo.id} className="grid__item card">
          <div className="card__body">
            <Link to={{ pathname: `/${photo.id}`, state: photo }}>
              <img src={photo.urls.small} alt="" />
            </Link>
            <Route path="/:photoId" component={ModalWrapper} />
          </div>
        </div>
      </Router>
    </>
  );
};
export default ListItem;

模态包装

import React from "react";
import Modal from "react-modal";
import { useHistory, useLocation } from "react-router-dom";

const customStyles = {
  content: {
    top: "50%",
    left: "50%",
    right: "auto",
    bottom: "auto",
    marginRight: "-50%",
    transform: "translate(-50%, -50%)"
  }
};

Modal.setAppElement("#root");

function ModalWrapper() {
  const history = useHistory();
  const location = useLocation();

  const photo = location.state;

  function downloadImage() {}

  function close() {
    history.push("/");
  }

  return (
    <Modal isOpen={true} onRequestClose={close} style={customStyles}>
      <img src={photo.urls.small} alt="" />

      <div>
        <button onClick={close} className="button">
          Close
        </button>
        <button onClick={downloadImage()}>Download</button>
      </div>
    </Modal>
  );
}

export default ModalWrapper;

【问题讨论】:

    标签: javascript reactjs react-router


    【解决方案1】:

    刷新页面时它不起作用的原因是您在导航时作为参数传递的photo 不再可用。但是,pathname 仍然可用(因为它是 URL 本身的一部分)

    因此,在ModalWrapper 页面上,您可以检查photo 是否不存在,然后基于pathname 中可用的id 进行新的API 调用以获取photo。我从未使用过 unsplash API,但我认为应该是 this API

    您的ModalWrapper 看起来像这样

    function ModalWrapper() {
      const history = useHistory();
      const location = useLocation();
      const [photo, setPhoto] = useState(location.state);
    
      useEffect(() => {
        if (location.pathname && !location.state) {
          // call the new API here using pathname (photo ID) and setPhoto
          console.log(location.pathname);
        }
      }, [location]);
    
      function downloadImage() {}
    
      function close() {
        history.push("/");
      }
    
      return (
        !!photo && (
          <Modal isOpen={true} onRequestClose={close} style={customStyles}>
            <img src={photo.urls.small} alt="" />
    
            <div>
              <button onClick={close} className="button">
                Close
              </button>
              <button onClick={downloadImage()}>Download</button>
            </div>
          </Modal>
        )
      );
    }
    

    您还没有问过这个问题,但是,我也会将RouterRoute 移到ListItem 之外,并将其保留在App.js 中(用路由器将所有内容都包装在其中)。将它保存在ListItem 中就像为每个列表项设置一个路由器和路由,这不是您理想中想要的。您可能希望在应用程序中保留一个路由器和路由,它通常属于App.js 或包装器或排序。这是更改后的codesandbox

    【讨论】:

    • 谢谢,刷新后错误不存在,但刷新时模式也不存在。其他照片显示在网格中,但是当我单击任何模式时,它们不会以模式打开,因为 URL 仍然是我打开的最后一个模式的链接。刷新后我是否仍然可以打开模式并能够关闭它并打开其他照片模式
    • 你告诉在那里调用 api。我在这个应用程序中使用了两个 api,一个用于随机生成照片,一个用于搜索 api,当用户搜索一个词时会调用它。那么在这种情况下,我应该打电话给哪个?
    • @gonnabefireifnohelp 您需要调用第三个 API,我也已将其链接到我的答案中。您可以使用照片 ID(路径名)获取照片
    • 我对 modalWrapper 做了一些改动。你能告诉我这是否是正确的方式codesandbox.io/s/awesome-meadow-vkn4o
    • 你很亲密。在这里,我解决了问题:codesandbox.io/s/hungry-boyd-mek1j
    猜你喜欢
    • 2023-03-27
    • 1970-01-01
    • 2021-04-16
    • 2019-06-01
    • 1970-01-01
    • 2023-03-19
    • 2012-11-15
    • 1970-01-01
    • 2021-10-30
    相关资源
    最近更新 更多