I have a component (ContainerMain.js) that fetches a list of containers from an API subsequently rendering each container name within a button. When one of the buttons are clicked, state will be passed to another component (ContainerContents.js) using "history.push(/containercontents/${id}, {container: container})". That works when I select a button in ContainerMain.js.
To handle when I refresh and input the url ("http://localhost:3000/containercontents/6") manually, that leads to ContainerContents.js being rendered, I use "props.match.params.id" to grab the id of the container and go from there.
This is as far as I have gotten because I don't know how to use only one source of data depending if that data comes from the url or the button. Does that make sense? Even if I did, this solution seems terrible and I feel like I am missing an obvious way of handling this scenario. I'm not very familiar with Redux/Context but I do believe I can use one of those to remedy this. I would just like to know if there is a simpler, more common way of handling this scenario before using Redux/Context, assuming I can use them to handle this.
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;