Jos passaan sen listan niin sitten pitää passata myös tieto siitä, mitä kenttää käytetään linkkinä (se siis voi olla joku muukin kuin name). Toiseksi omaan arkkitehtooniseen silmään sattuu paremmin ajatus siitä, että LinkListin ei tarvitse tietää miltä nuo objektit näyttävät.
Tuota defaulttia yritin, mutta jotain meni syntaksissa pieleen. Varmaan tappelin samaan aikaan jonkun muun jutun kanssa, ja oletin virheellisesti, että vika on tuossa. Listan transformoinnissa kaipaan kovasti list comprehensionia, jota ei näköjään JS:stä löydy
Tuo rakenne ajaa kyllä aika lailla saman asian, eipähän vain tuollaista esimerkkiä sattunut silmään.
Nyt on kyllä sellainen setState-hässäkkä, että taitaa setvimiseen mennä tovi. Täytynee alkaa tutustua error boundareihin seuraavaksi, että saa hommasta jotain selkoa.
Koodi:
Warning: Cannot update a component (`Magazine`) while rendering a different component (`Issue`).
Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
The above error occurred in the <Issue> component:
Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.
Tuo "The above error occured" vaan viittaa ihan yhden tietueen määrittelyyn (main menun), joten ei ollut kovin hyödyllinen.
Yritän siis saada palautettua lehden numeroa issuelta magazinelle. Tämä näytetään accordiontabin otsikkona. Totesin, että jos lataan koko issue-tiedon magazinelle, niin magazines-sivun lataaminen kestää aivan liian kauan, joten muokkasin API:t uusiksi niin, että sieltä ei tule ylimääräistä dataa. Esimerkiksi issuesta riittää muuten magazinelle id:t, paitsi tuon yhden kentän osalta. Toisaalta eipä sen otsikon sisällön päättäminen myöskään loogisesti muutenkin kuulu magazinelle vaan issuelle.
Ideana siis jokseenkin tällainen (magazine):
Koodi:
const [issues, setIssue]: [string[], (issue: string[]) => void] = React.useState<string[]>([]);
...
const getIssueHeader = (index: number): string => {
if (issues.length >= index) {
return issues[index];
} else {
return "";
}
}
const issueNumber = (coverNumber: string, index: number): void => {
let newArray = [...issues];
newArray[index] = coverNumber;
setIssue(newArray);
}
..
<Accordion multiple activeIndex={[0]}>
{
magazine.issues
.sort(issueSort)
.map((issue, index) => (
<AccordionTab key={issue.id}
header={getIssueHeader(index)}>
<Issue
id={issue.id}
updateName={issueNumber}
index={index}
/>
</AccordionTab>
))
}
</Accordion>
Issuessa sitten
Koodi:
export type IssueProps = {
id: number | null,
updateName?: (arg: string, index: number) => void,
index?: number
};
...
export const Issue = ({ id, updateName, index }: IssueProps) => {
...
if (!issue) return null;
if (updateName && index) {
updateName(issue.cover_number, index);
}
Viimeinen kohta on ennen return-lauseketta. Magazine aukeaa ihan oikein, mutta jos klikkaan jonkun toisen tabin auki, niin pasauttaa nuo virheet.
Jaahas, taas kävi klassiset. Samalla kun sain tämän viestin kirjoitettua, niin tajusin missä vika. Tuo viimeinen koodi piti siirtää useEffectin sisään setIssue():n jälkeen (tsekkaan lisäksi vielä samassa että issue ei ole null) ja kappas, homma alkoi muuten toimimaan, paitsi että tuo otsikko ei päivity edelleenkään. Tuo arrayn kopiointi on tuolla sen vuoksi että ajattelin että sillä saan pakotettua näkymään rendaamaan uudestaan, jolloin headeri päivittyisi.