我正在尝试使用<Redirect>
中的react-router-dom
重定向页面。唯一的问题是它会更改URL,但不会像预期的那样重新加载页面。
App.js
import React from "react";
import "./Style.css";
import Gallery from "./components/layout/Gallery";
import Preview from "./components/layout/Preview";
import Header from "./components/layout/Header";
import { HashRouter as Router, Switch, Route } from "react-router-dom";
function App() {
return (
<Router>
<>
<Header />
<Switch>
<Route path="/" exact component={Gallery} />
<Route path="/:id" component={Preview} /> /////////THIS IS WHAT I'M FOCUSING AT (Preview)///////
</Switch>
<footer>
<span className="footer-text">Made by Luis 2020©</span>
</footer>
</>
</Router>
);
}
export default App;
Preview.js
import React, { useState, useEffect } from "react";
import { Redirect } from "react-router-dom";
function Preview({ match }) {
const [imageName, setImageName] = useState();
const [images, setImages] = useState();
const [finishedLoading, setFinishedLoading] = useState(false);
const [nextPage, setNextPage] = useState();
const [prevPage, setPrevPage] = useState();
const [toNextPage, setToNextPage] = useState();
const [toPrevPage, setToPrevPage] = useState();
function setPages() {
let currentIndex = 0;
let nextIndex = 0;
let prevIndex = 0;
if (finishedLoading) {
//Sets current page
Object.keys(images).map((image, index) => {
if (image === imageName) currentIndex = index;
});
//Sets next page
nextIndex = currentIndex + 1;
if (nextIndex > 0) setNextPage(Object.keys(images)[nextIndex]);
else setNextPage(null);
//Sets previous page
prevIndex = currentIndex - 1;
if (prevIndex > 0) setPrevPage(Object.keys(images)[prevIndex]);
else setPrevPage(null);
}
}
function importAll(r) {
let images_ = {};
r.keys().map((item, index) => {
images_[item.replace("./", "")] = r(item);
});
setFinishedLoading(true);
return images_;
}
function toTitle(str) {
return str
.split(" ")
.map(function (ele) {
return ele[0].toUpperCase() + ele.slice(1).toLowerCase();
})
.join(" ");
}
useEffect(() => {
setImageName(String(match.params.id));
setImages(importAll(require.context("../images", false, /\.jpg/)));
}, []);
useEffect(() => {
if (finishedLoading) setPages();
}, [finishedLoading, imageName]);
useEffect(() => {
setToNextPage(false);
}, [toNextPage]);
useEffect(() => {
setToPrevPage(false);
}, [toPrevPage]);
return (
<>
{toNextPage ? <Redirect to={`/${nextPage}`} /> : null} ////////IMPORTANT
{toPrevPage ? <Redirect to={`/${prevPage}`} /> : null} ////////IMPORTANT
{images === undefined || images === null ? (
<img
className="loading"
key="loading"
src={loading}
alt="Loading..."
width="100"
/>
) : (
<>
<h2 className="preview-title">
{toTitle(imageName.replace(".jpg", "").replace(/-/g, " "))}
</h2>
<div className="preview">
<img
src={images[imageName]}
alt={String(imageName)}
key={String(imageName)}
width="400"
/>
</div>
<div className="nav-buttons">
<button onClick={() => setToNextPage(true)}><</button> ////IMPORTANT
<button onClick={() => setToPrevPage(true)}>></button> ////IMPORTANT
</div>
</>
)}
</>
);
}
export default Preview;
答案 0 :(得分:1)
您的代码中的问题是您使用重定向来实际更改仅更改Route参数的页面。这里发生的是,在这种情况下,Preview组件不会重新安装,而是使用不同的match参数重新渲染。
在这种情况下,由于未重置toNextPage和toPrevPage值,因此您的组件将继续执行重定向。
您还具有以下useEffect代码
useEffect(() => {
setImageName(String(match.params.id));
setImages(importAll(require.context("../images", false, /\.jpg/)));
}, []);
由于它具有空的依赖关系,因此在参数更改时不会执行
总体您可以通过改用history.push或重定向
来改善上述代码import React, { useState, useEffect } from "react";
import { Redirect } from "react-router-dom";
function Preview({ match }) {
const [imageName, setImageName] = useState();
const [images, setImages] = useState();
const [finishedLoading, setFinishedLoading] = useState(false);
const [nextPage, setNextPage] = useState();
const [prevPage, setPrevPage] = useState();
function setPages() {
let currentIndex = 0;
let nextIndex = 0;
let prevIndex = 0;
if (finishedLoading) {
//Sets current page
Object.keys(images).map((image, index) => {
if (image === imageName) currentIndex = index;
});
//Sets next page
nextIndex = currentIndex + 1;
if (nextIndex > 0) setNextPage(Object.keys(images)[nextIndex]);
else setNextPage(null);
//Sets previous page
prevIndex = currentIndex - 1;
if (prevIndex > 0) setPrevPage(Object.keys(images)[prevIndex]);
else setPrevPage(null);
}
}
function importAll(r) {
let images_ = {};
r.keys().map((item, index) => {
images_[item.replace("./", "")] = r(item);
});
setFinishedLoading(true);
return images_;
}
function toTitle(str) {
return str
.split(" ")
.map(function (ele) {
return ele[0].toUpperCase() + ele.slice(1).toLowerCase();
})
.join(" ");
}
useEffect(() => {
setImageName(String(match.params.id));
setImages(importAll(require.context("../images", false, /\.jpg/)));
}, [match.params.id]);
useEffect(() => {
if (finishedLoading) setPages();
}, [finishedLoading, imageName]);
const changePage = (page) => {
history.push(`/${page}`);
}
return (
<>
{images === undefined || images === null ? (
<img
className="loading"
key="loading"
src={loading}
alt="Loading..."
width="100"
/>
) : (
<>
<h2 className="preview-title">
{toTitle(imageName.replace(".jpg", "").replace(/-/g, " "))}
</h2>
<div className="preview">
<img
src={images[imageName]}
alt={String(imageName)}
key={String(imageName)}
width="400"
/>
</div>
<div className="nav-buttons">
<button onClick={() => changePage(nextPage)}><</button> ////IMPORTANT
<button onClick={() => changePage(prevPage)}>></button> ////IMPORTANT
</div>
</>
)}
</>
);
}
export default Preview;