Component is not updated using useState
Unanswered
.doodeedoo posted this in #help-forum
Trying out a basic example. I'm new at NextJS, so it might be something really simple.
I've removed the non-important lines. I just want to click on a button, and a component should update it's value. The correct number is shown in a alert box, so don't focus on the missing code, it's working fine up until the alert.
What am I doing wrong / missing?
TYIA!
export default async function Page(pageProps: PageProps) {
const [selectedLabel, setSelectedLabel] = useState("");
function showLabel(LID: string) {
alert("setSelectedLabel = " + LID);
setSelectedLabel(LID);
}
....
return (
....
<button onClick={() => showLabel(aLabel.l.properties.LID.toString())}>Show label</button>
<LabelComponent LID={selectedLabel} />
...
} // end of page
Here is LabelComponent;
interface ComponentProps {
LID: string;
}
const LabelComponent = (props: ComponentProps) => {
return (
<div>
<h1>{props.LID}</h1>
</div>
)
}
export default LabelComponent;
I've removed the non-important lines. I just want to click on a button, and a component should update it's value. The correct number is shown in a alert box, so don't focus on the missing code, it's working fine up until the alert.
What am I doing wrong / missing?
TYIA!
export default async function Page(pageProps: PageProps) {
const [selectedLabel, setSelectedLabel] = useState("");
function showLabel(LID: string) {
alert("setSelectedLabel = " + LID);
setSelectedLabel(LID);
}
....
return (
....
<button onClick={() => showLabel(aLabel.l.properties.LID.toString())}>Show label</button>
<LabelComponent LID={selectedLabel} />
...
} // end of page
Here is LabelComponent;
interface ComponentProps {
LID: string;
}
const LabelComponent = (props: ComponentProps) => {
return (
<div>
<h1>{props.LID}</h1>
</div>
)
}
export default LabelComponent;
15 Replies
can you post your code using code block and sytax highlihgting like this
```js
paste code here
```
```js
paste code here
```
export default async function Page(pageProps: PageProps) {
const [selectedLabel, setSelectedLabel] = useState("");
function showLabel(LID: string) {
alert("setSelectedLabel = " + LID);
setSelectedLabel(LID);
}
....
return (
....
<button onClick={() => showLabel(aLabel.l.properties.LID.toString())}>Show label</button>
<LabelComponent LID={selectedLabel} />
...
} // end of page
Here is LabelComponent;
interface ComponentProps {
LID: string;
}
const LabelComponent = (props: ComponentProps) => {
return (
<div>
<h1>{props.LID}</h1>
</div>
)
}
export default LabelComponent;try
function showLabel(LID: string) {
alert("setSelectedLabel = " + LID);
console.log("value: "+LID)
setSelectedLabel(LID);
}The conole output is the same as in the alert box ("3").
@.doodeedoo The conole output is the same as in the alert box ("3").
have you tried creating a client component for that? instead of doing in a page component which is supposed to be server only,
I've this statement in the top of the file, I've read it should work. I only tried different things inside this file.
'use client';
'use client';
I mean in the top of page.tsx
Also, I don't really know how to do what you ask. I thought the whole point with useState is that it automagically detects what parts of the page / components to re-evaluate...?
you're not supposed to do 'use client' on page component
create a child component that uses 'use client' and put useState there
Ok, I refactored the code below. It's the exact same result. The ID is being written to the console, but the html is not updated.
import PageProps from "../../../types/PageProps";
import LabelTable from "../../../components/LabelTable";
export default async function Page(pageProps: PageProps) {
return (
<div>
<LabelTable />
</div>
);
}
---------------------
'use client';
interface ComponentProps {
LID: string;
}
const LabelComponent = (props: ComponentProps) => {
return (
<h1>{props.LID}</h1>
)
}
export default LabelComponent;'use client';
import { Integer, Node } from "neo4j-driver";
import { useState } from "react";
import LabelProperties from "../types/properties/LabelProperties";
import { LABELLED } from "../types/relationships/LABELLED";
import ProductProperties from "../types/properties/ProductPropeties";
import { read } from "../lib/neo4j";
import LabelComponent from "./LabelComponent";
type PageResult = {
l: Node<Integer, LabelProperties>;
r: LABELLED;
p: Node<Integer, ProductProperties>;
}
const LabelTable = async () => {
const [selectedLabel, setSelectedLabel] = useState("");
function showLabel(LID: string) {
console.log("ID: " + LID);
setSelectedLabel(LID);
}
const result = await read<PageResult>(
`
MATCH (p:Product {SKU : 'ID-00092'})-[r:LABELLED]->(l:Label)
RETURN r, l, p
ORDER BY r.created
`
);
return (
<table width="100%">
<thead></thead>
<tbody>
<tr>
<td>
<ul>
{result.map((aLabel) => (
<li key={aLabel.l.properties.LID.toString()}>
<button onClick={() => showLabel(aLabel.l.properties.LID.toString())}>Show label</button>
<span>{aLabel.r.properties.created.toString()} (ID: {aLabel.l.properties.LID.toString()})</span>
</li>
))}
</ul>
</td>
<td>
<LabelComponent LID={selectedLabel} />
</td>
</tr>
</tbody>
</table>
)
}
export default LabelTable;client component can't be async @.doodeedoo
Ok - solved it by making the page query the db, setting the data as a prop on a client component. It would have been helpful to have gotten warnings on;
my attempt at using async on the client component
my attempt at using 'use client' on a page
Thanks for the pointers @alfon ðŸ‘
my attempt at using async on the client component
my attempt at using 'use client' on a page
Thanks for the pointers @alfon ðŸ‘
no problem, yeah the error log could be better haha