Reputation: 2191
I'm trying to get a functional component to force a rerender whenever the testFn
executes. I thought to use state to do this (if there's a better way then please speak up), which appears to successfully force a rerender but only twice, then nothing.
I built a simple demo to emulate the issue as using my real app is too difficult to demonstrate but the same principles should presumably apply (my real demo fetches data when the function executes and displays it on the page, but it's not rerendering and I have to refresh the page to see the new data, hence why I want to trigger a rerender).
import React, { useState } from "react";
const App = () => {
const [, rerender] = useState(false);
const testFn = () => {
console.log("test Fn");
rerender(true);
};
return (
<div>
<p>test</p>
<button onClick={testFn}>clickk</button>
{console.log("render")}
</div>
);
};
export default App;
I've also made a Stackblitz demo for conveinence.
Can anyone solve this demo or think of a better way of implementing it?
Thanks for any help here.
Upvotes: 6
Views: 13968
Reputation: 150
I've had this same question. I've found that you could also pass down a function into a child component. Watch for a state change of the function from the parent component with a useEffect. And when the function is invoked in the child component, it will force a rerender in the parent component for the child component.
Upvotes: 0
Reputation: 944530
It triggers a re-render when the state changes.
The first time you click the button you change the state from false
to true
so a rerender is triggered.
Subsequent clicks you change it from true
to true
which isn't a change, so it doesn't.
You could toggle it:
const [render, rerender] = useState(false);
and
rerender(!render);
so it actually changes.
… but this smells of being an XY Problem, and you should probably be changing something which is actually being rendered.
Upvotes: 9
Reputation: 371193
State is the right way, since state changes are the primary way to cause re-renders. I'd increment a counter:
const [, setCount] = useState(0);
// force a re-render by running:
setCount(c => c + 1)
But this is still a very odd thing to do. In almost all cases, a much more elegant solution will be implementable, such as by putting data that changes into state, and calling the state setter when the data updates.
Upvotes: 6