JavaScript: Wie kann ich Daten zwischen zwei Dateien verteilen?
Hallo zusammen,
ich bitte euch um Hilfe bei meinem Problem. Und zwar muss ich im Studium eine Seite so nachbauen, dass ich mittels einer Filterauswahl eine Liste ausgeben kann.
Letztens haben wir gelernt, dass wir den Code anhand Komponenten aufteilen sollen. Ich habe also die Komponenten Titelleiste (wo der Filter, Logo und Titel enthalten sein sollte), Tabelle und Filter erstellt.
Zudem gibt es ja diese Hauptdatei App.js. In einem ersten Schritt habe ich in der Filter.js Funktionen geschrieben, um meine Daten gemäß der möglichen Suchbegriffe zu filtern und habe den aktuellen Wert, welcher vom Nutzer gewählt wird, in einem useState abgespeichert.
Wie kann ich diesen Wert nun der Tabelle.js übergeben, damit dort anhand der Filterung die Ausgabe generiert werden kann?
ChatGPT hat mir geraten, die Daten zuerst in die App.js zu schreiben. Aber wie geht das? Wie komme ich von einem Child in das Parent?
Ich denke, ihr erkennt, dass ich leider noch sehr unerfahren im Programmieren bin.
Folgend die Codes:
App.js:
const Titelseite = () => {
return (
<div className="titelseite-container">
<BasicTable />
</div>
);
};
const Tabelle = () => {
return (
<div className="tabelle">
<div>Tabellenleiste</div>
</div>
);
};
function App() {
const [service_ausg, setService] = useState("");
const [anbieter_ausg, setAnbieter] = useState("");
const handleServiceChange = (value) => {
setService(value);
};
const handleAnbieterChange = (e) => {
setAnbieter(e);
};
return (
<div className="App">
<Titelleiste>
<Filter
onChangeService={handleServiceChange}
onChangeAnbieter={handleAnbieterChange}
/>
<BasicTable />
</Titelleiste>
<Titelseite />
</div>
);
}
export default App;
Titelleiste.js:
import Grid from "@mui/material/Grid2";
import { Filter } from "./Filter";
import { useState } from "react";
import data from "./data/tableData.json";
export const Titelleiste = () => {
const getData = (data) => {
console.log("Ich bin in Titelleiste und komme von Filter");
};
return (
<Grid container spacing={2}>
<Grid item size={4}>
<p>
<img src="geoharvester.png" width="100px" height="50px" />
</p>
</Grid>
<Grid item size={4}>
<p>Ein Katalog für schweizer Geodienste</p>
</Grid>
<Grid item size={4} container justifyContent="flex-end">
<p>
<Filter onChange={getData} />
</p>
</Grid>
</Grid>
);
};
Filter.js :
import "./App.css";
import { useState } from "react";
import InputLabel from "@mui/material/InputLabel";
import MenuItem from "@mui/material/MenuItem";
import FormHelperText from "@mui/material/FormHelperText";
import FormControl from "@mui/material/FormControl";
import Select from "@mui/material/Select";
import data from "./data/tableData.json";
import { App } from "./App";
export const Filter = ({ onChangeService, onChangeAnbieter }) => {
let array_service = data.map((element) => element.service);
let array_service_ausg = [...new Set(array_service)]; //* new "Set", entfernt automatisch die Duplikate und erstellt ein neues Objekt. Das neue Objekt wird mittels den "..." in eine Liste gespeichert
let array_anbieter = data.map((element) => element.anbieter);
let array_anbieter_ausg = [...new Set(array_anbieter)];
const funService = (e) => {
const [service_ausg, setService] = useState("");
setService(e.target.value);
};
const funAnbieter = (e) => {
TransferAnbieter(e.target.value);
};
return (
<div>
<form>
<Select name="service" onChange={funService} sx={{ width: 100 }}>
{array_service_ausg.map((service) => (
<MenuItem value={service}>{service}</MenuItem>
))}
</Select>
</form>
<Select name="anbieter" onChange={funAnbieter} sx={{ width: 100 }}>
{array_anbieter_ausg.map((anbieter) => (
<MenuItem value={anbieter}>{anbieter}</MenuItem>
))}
</Select>
<br />
</div>
);
};
Nach einigen Stunden, die ich bereits in die Recherche meines Problems investiert habe, danke ich euch herzlich für eure Hilfe.
1 Antwort
Edit:
Ich war etwas kurz angebunden und habe deine Frage mangels Syntax-Hervorhebung (was jetzt korrigiert wurde) völlig falsch verstanden. Daher jetzt nochmal als Nachtrag darauf eingehen möchte. Um die ausgewählten Werte an die Tabelle weiterzugeben, muss der Zustand der Filter in der App.js (u.a. useState) verwaltet werden.
Die ausgewählten Werte aus der Filter-Komponente werden mit einer Callback-Funktion an die App.js übergeben und in dann in der useState gespeichert. Du kannst sie dann von dort aus als Props an die Tabellen-Komponente durchreichen. Wenn der User die Werte der Filter verändert, wird die Tabelle dynamisch aktualisiert.
Ich würde zudem das State-Management anpassen und dahingehend optimieren, indem unnötige Teile rausfliegen oder gekürzt werden. Dasselbe gilt für deine Imports, die sich auch kompakter schreiben lassen. Da musst du nicht immer wieder für jede Komponente von Material UI einen eigenen Import schreiben.
App.js
import { useState } from "react";
import { Titelleiste } from "./Titelleiste";
import { Filter } from "./Filter";
import { Tabelle } from "./Tabelle";
function App() {
// State für beide Filter
const [filter, setFilter] = useState({ service: "", anbieter: ""});
// Update (service und anbieter)
const handleFilterChange = (key, value) => {
setFilter((prev) => ({ ...prev, [key]: value }));
};
return (
<div className="App"> <Titelleiste />
<Filter onFilterChange={handleFilterChange} />
<Tabelle filter={filter} /> </div>
);
}
export default App;
Filter.js
import { FormControl, InputLabel, MenuItem, Select } from "@mui/material";
import data from "./data/tableData.json";
export const Filter = ({ onFilterChange }) => {
// Werte für service
const array_service = [...new Set(data.map((item) => item.service))];
// Werte für anbieter
const array_anbieter = [...new Set(data.map((item) => item.anbieter))];
// Handler für Eingaben
const handleChange = (key) => (e) => {
onFilterChange(key, e.target.value);
};
return (
<div>
<FormControl sx={{ width: 100 }}>
<InputLabel>Service</InputLabel>
<Select onChange={handleChange("service")}>
{array_service.map((service) => (
<MenuItem key={service} value={service}>
{service}
</MenuItem>
))}
</Select>
</FormControl>
<FormControl sx={{ width: 100, marginLeft: 2 }}>
<InputLabel>Anbieter</InputLabel>
<Select onChange={handleChange("anbieter")}>
{array_anbieter.map((anbieter) => (
<MenuItem key={anbieter} value={anbieter}>
{anbieter}
</MenuItem>
))}
</Select>
</FormControl>
</div>
);
};
Tabelle.js
import data from "./data/tableData.json";
export const Tabelle = ({ filter }) => {
// Gefiltere Daten (ausgewählte Filter)
const filteredData = data.filter((item) => {
return (
(!filter.service || item.service === filter.service) &&
(!filter.anbieter || item.anbieter === filter.anbieter)
);
});
return (
<div className="tabelle">
{filteredData.length > 0 ? (
<table>
<thead>
<tr>
<th>Service</th>
<th>Anbieter</th>
</tr>
</thead>
<tbody>
{filteredData.map((row) => (
<tr key={row.id}>
<td>{row.service}</td>
<td>{row.anbieter}</td>
</tr>
))}
</tbody>
</table>
) : (
<div>Keine Daten verfügbar</div>
)}
</div>
);
};