App.tsx:
import Router from "./components/Router.tsx"
import {useState} from "react"
import Car from "./components/Car.tsx"
export default function App() {
const [items, setItems] = useState<Car[]>([])
function addItem(newItem: Car) {
setItems([...items, newItem])
}
const props = {
items: items,
setItems: setItems,
addItem: addItem
}
return (
<>
<Router props={props}/>
</>
)
}
Router.tsx:
import {BrowserRouter, Routes, Route} from "react-router-dom";
import MainPage from "../pages/MainPage.tsx";
import AddPage from "../pages/AddPage.tsx";
import ReadPage from "../pages/ReadPage.tsx";
import UpdatePage from "../pages/UpdatePage.tsx";
import Car from "../components/Car.tsx"
import {Dispatch, SetStateAction} from "react"
interface Props {
items: Car[],
setItems: Dispatch<SetStateAction<Car[]>>;
addItem: (newItem: Car) => void;
}
export default function Router({props}: { props: Props }) {
return (
<>
<BrowserRouter>
<Routes>
<Route index element={<MainPage props={props}/>}></Route>
<Route path="/home" element={<MainPage props={props}/>}></Route>
<Route path="/add" element={<AddPage props={props}/>}></Route>
<Route path="/read" element={<ReadPage props={props}/>}></Route>
<Route path="/update" element={<UpdatePage props={props}/>}></Route>
<Route path="*" element={<MainPage props={props}/>}></Route>
</Routes>
</BrowserRouter>
</>
)
}
AddPage.tsx:
import AddForm from "../components/AddForm.tsx"
import Car from "../components/Car.tsx"
import {Dispatch, SetStateAction} from "react"
interface Props {
items: Car[];
setItems: Dispatch<SetStateAction<Car[]>>;
addItem: (newItem: Car) => void;
}
export default function AddPage({props}: { props: Props }) {
return (
<>
<AddForm props={props}/>
</>
)
}
MainPage.tsx:
import List from "../components/List.tsx";
import Car from "../components/Car.tsx";
import {Dispatch, SetStateAction} from "react";
interface Props {
items: Car[];
setItems: Dispatch<SetStateAction<Car[]>>;
addItem: (newItem: Car) => void;
}
export default function MainPage({props}: { props: Props }) {
const handleAddClick = () => {
window.open("/add", "_blank");
}
const handleReadClick = () => {
window.open("/read", "_blank");
}
const handleUpdateClick = () => {
window.open("/update", "_blank");
}
return (
<>
<button className="border rounded" onClick={handleAddClick}>add</button>
<List props={props} onReadClick={handleReadClick} onUpdateClick={handleUpdateClick}
/>
</>
)
}
List.tsx:
import Car from "./Car.tsx";
import {Dispatch, SetStateAction} from "react";
interface Props {
items: Car[];
setItems: Dispatch<SetStateAction<Car[]>>;
addItem: (newItem: Car) => void;
}
export default function List({props, onReadClick, onUpdateClick}: { props: Props, onReadClick: () => void, onUpdateClick: () => void }) {
const items = props.items;
// TODO update the list with the new item added
const handleRead = () => {
onReadClick();
}
const handleUpdate = () => {
onUpdateClick();
}
const handleDelete = () => {
// TODO
}
return (
<>
<ul className="list-group">
{items.map((item, index) =>
<li className="list-group-item border rounded" key={index}>
{item.model}
<button className="border rounded" onClick={handleRead}>read</button>
<button className="border rounded" onClick={handleUpdate}>update</button>
<button className="border rounded" onClick={handleDelete}>delete</button>
</li>)
}
</ul>
</>
)
}
AddForm.tsx:
import Car from "./Car.tsx";
import {ChangeEvent, Dispatch, SetStateAction, useState} from "react"
interface Props {
items: Car[];
setItems: Dispatch<SetStateAction<Car[]>>;
addItem: (newItem: Car) => void;
}
export default function AddForm({props}: { props: Props }) {
const [formData, setFormData] = useState({brand: "", model: "", year: 0})
const addItem = props.addItem;
const handleInputChange = (event: ChangeEvent<HTMLInputElement>) => {
const changedField = event.target.name;
const newValue = event.target.value;
setFormData(currentData => {
return {
...currentData,
[changedField]: newValue
}
})
}
const handleAdd = () => {
addItem(new Car(formData.brand, formData.model, formData.year));
}
return (
<form className="position-absolute top-50 start-50 translate-middle">
<input id="input-car-brand" name="brand" placeholder="brand" onChange={handleInputChange}/>
<input id="input-car-model" name="model" placeholder="model" onChange={handleInputChange}/>
<input id="input-car-year" name="year" placeholder="year" onChange={handleInputChange}/>
<button className="border rounded" type="button" onClick={handleAdd}>add
</button>
</form>
);
}`
The app will render the MainPage first, where I have a button "add", which when it is pressed it will open the AddPage in a new tab with a form to input values for a new object Car. When I press "add" in the AddPage, it won't cause a re render on the MainPage to display the new list of items.
I tried using Context but still didn't work.