我有一个组件 (ContainerMain.js),它从 API 中获取容器列表,随后在按钮中呈现每个容器名称。单击其中一个按钮时,状态将使用“history.push(/containercontents/${id}, {container: container})”传递给另一个组件 (ContainerContents.js)。 当我在 ContainerMain.js 中选择一个按钮时,这会起作用。
为了处理当我手动刷新和输入 url(“http://localhost:3000/containercontents/6”)时导致 ContainerContents.js 被渲染,我使用“props.match.params.id”来获取容器的 ID 并从那里开始。
这是我所了解的,因为我不知道如何只使用一个数据源,具体取决于该数据是来自 url 还是来自按钮。那有意义吗?即使我这样做了,这个解决方案看起来也很糟糕,我觉得我缺少一种处理这种情况的明显方法。我对 Redux/Context 不是很熟悉,但我相信我可以使用其中之一来解决这个问题。我只想知道在使用 Redux/Context 之前是否有更简单、更通用的方法来处理这种情况,假设我可以使用它们来处理这个问题。
ContainerMain.js
import React, { useState, useEffect } from 'react'
import { Link, Route, useHistory } from 'react-router-dom'
import ContainerContents from './ContainerContents';
const ContainerMain = (props) => {
const [containers, setContainers] = useState([]);
// const [showContainerContents, setShowContainerContents] = useState(false);
// const [selectedContainerId, setSelectedContainerId] = useState();
const history = useHistory();
const getContainers = async () => {
const url = "/api/containers";
await fetch(url)
.then(response => response.json())
.then(response => setContainers(response))
.catch(() => console.log("Can’t access " + url + " response. Blocked by browser?"))
}
const deleteContainer = async (containerId) => {
let result = window.confirm("Are you sure you want to delete your " + containers.find(container => container.id === containerId).name + "?");
if (result) {
setContainers(containers.filter(container => container.id !== containerId))
fetch(`api/containers/${containerId}`, {
method: 'DELETE',
})
.then(res => res.json()) // or res.json()
.then(res => console.log(res))
}
else {
return
}
}
// const onButtonClick = (containerId) => {
// setShowContainerContents(true)
// setSelectedContainerId(containerId)
// }
useEffect(() => {
getContainers();
}, []);
return (
<div>
<strong>MY FOOD CONTAINERS</strong>
<br></br><br></br>
<ul>
{containers.map(container => (
<li key={container.id}>
<div>
<button onClick={() => deleteContainer(container.id)} className="button is-rounded is-danger">Delete</button>
<button onClick={() => history.push(`/containercontents/${container.id}`, {container: container})} className="button is-primary">{container.name}</button>
{/* <Route
path="/ContainerContents" component={HomePage}/> */}
{/* <Link to={`/containercontents/${container.id}`}>{container.name}</Link> */}
{/* <Link to={{
pathname: `/containercontents/${container.name}`,
state: {container: container}
}}>{container.name}
</Link> */}
</div>
</li>
))}
</ul>
{/* {showContainerContents ? <ContainerContents containerId={selectedContainerId} /> : null} */}
</div>
);
}
export default ContainerMain;
ContainerContents.js
import React, { useEffect, useState} from 'react';
const ContainerContents = (props) => {
const [container, setContainer] = useState({});
useEffect(() => {
const fetchContainer = async () => {
const { id } = props.match.params;
console.log("This is the id: " + id)
let url = `/api/containers/${id}`;
await fetch(url)
.then(response => response.json())
.then(response => setContainer(response))
.catch(() => console.log("Can’t access " + url + " response. Blocked by browser?"))
}
fetchContainer();
}, [props.match.params]);
return (
<div>
{/* will not work when I refresh and enter url as expected*/}
<h1>{props.location.state.container.name}</h1>
<h1>{container.name}</h1>
</div>
)
}
export default ContainerContents;
最佳答案
据我了解,您希望能够在使用该方法时从按钮点击中获取 id,而在手动访问时从 url 中获取 id。
一个简单的方法可能是在 props.match.params 不存在的情况下从 url 中检索 id?您应该能够使用 useLocation Hook 来访问它,然后我确定有一种更简单的方法,但您可以只解析您想要的 ID。
喜欢:
const location = useLocation();
let url_segs = location.pathname.split("/");
let id = url_segs[url_segs.length - 1]
另外我相信 react-router-dom 现在支持 useParams如果您有兴趣,可以使用更简单的方法访问参数。
关于javascript - 当用户手动输入 URL 而不是通过链接输入时如何处理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62855095/