score:304
🎉 you can now, using react hooks
using react hooks, you can now call usestate()
in your function component.
usestate()
will return an array of 2 things:
- a value, representing the current state.
- its setter. use it to update the value.
updating the value by its setter will force your function component to re-render,
just like forceupdate
does:
import react, { usestate } from 'react';
//create your forceupdate hook
function useforceupdate(){
const [value, setvalue] = usestate(0); // integer state
return () => setvalue(value => value + 1); // update state to force render
// an function that increment 👆🏻 the previous state like here
// is better than directly setting `value + 1`
}
function mycomponent() {
// call your hook here
const forceupdate = useforceupdate();
return (
<div>
{/*clicking on the button will force to re-render like force update does */}
<button onclick={forceupdate}>
click to re-render
</button>
</div>
);
}
the component above uses a custom hook function (useforceupdate
) which uses the react state hook usestate
. it increments the component's state's value and thus tells react to re-render the component.
edit
in an old version of this answer, the snippet used a boolean value, and toggled it in forceupdate()
. now that i've edited my answer, the snippet use a number rather than a boolean.
why ? (you would ask me)
because once it happened to me that my forceupdate()
was called twice subsequently from 2 different events, and thus it was reseting the boolean value at its original state, and the component never rendered.
this is because in the usestate
's setter (setvalue
here), react
compare the previous state with the new one, and render only if the state is different.
score:0
for me just updating the state didn't work. i am using a library with components and it looks like i can't force the component to update.
my approach is extending the ones above with conditional rendering. in my case, i want to resize my component when a value is changed.
//hook to force updating the component on specific change
const useupdateonchange = (change: unknown): boolean => {
const [update, setupdate] = usestate(false);
useeffect(() => {
setupdate(!update);
}, [change]);
useeffect(() => {
if (!update) setupdate(true);
}, [update]);
return update;
};
const mycomponent = () => {
const [mystate, setmystate] = usestate();
const update = useupdateonchange(mystate);
...
return (
<div>
... ...
{update && <librarycomponent />}
</div>
);
};
you need to pass the value you want to track for change. the hook returns boolean which should be used for conditional rendering.
when the change value triggers the useeffect update goes to false which hides the component. after that the second useeffect is triggered and update goes true which makes the component visible again and this results in updating (resizing in my case).
score:1
this can be done without explicitly using hooks provided you add a prop to your component and a state to the stateless component's parent component:
const parentcomponent = props => {
const [updatenow, setupdatenow] = usestate(true)
const updatefunc = () => {
setupdatenow(!updatenow)
}
const mycomponent = props => {
return (<div> .... </div>)
}
const mybuttoncomponent = props => {
return (<div> <input type="button" onclick={props.updatefunc} />.... </div>)
}
return (
<div>
<mycomponent updateme={updatenow} />
<mybuttoncomponent updatefunc={updatefunc}/>
</div>
)
}
score:1
the accepted answer is good. just to make it easier to understand.
example component:
export default function mycomponent(props) {
const [updateview, setupdateview] = usestate(0);
return (
<>
<span style={{ display: "none" }}>{updateview}</span>
</>
);
}
to force re-rendering call the code below:
setupdateview((updateview) => ++updateview);
score:1
none of these gave me a satisfactory answer so in the end i got what i wanted with the key
prop, useref and some random id generator like shortid
.
basically, i wanted some chat application to play itself out the first time someone opens the app. so, i needed full control over when and what the answers are updated with the ease of async await.
example code:
function sleep(ms) {
return new promise(resolve => settimeout(resolve, ms));
}
// ... your jsx functional component, import shortid somewhere
const [render, rerender] = usestate(shortid.generate())
const messagelist = useref([
new message({id: 1, message: "hi, let's get started!"})
])
useeffect(()=>{
async function _ () {
await sleep(500)
messagelist.current.push(new message({id: 1, message: "what's your name?"}))
// ... more stuff
// now trigger the update
rerender(shortid.generate())
}
_()
}, [])
// only the component with the right render key will update itself, the others will stay as is and won't rerender.
return <div key={render}>{messagelist.current}</div>
in fact this also allowed me to roll something like a chat message with a rolling .
const waitchat = async (ms) => {
let text = "."
for (let i = 0; i < ms; i += 200) {
if (messagelist.current[messagelist.current.length - 1].id === 100) {
messagelist.current = messagelist.current.filter(({id}) => id !== 100)
}
messagelist.current.push(new message({
id: 100,
message: text
}))
if (text.length === 3) {
text = "."
} else {
text += "."
}
rerender(shortid.generate())
await sleep(200)
}
if (messagelist.current[messagelist.current.length - 1].id === 100) {
messagelist.current = messagelist.current.filter(({id}) => id !== 100)
}
}
score:1
if you are using functional components with version < 16.8. one workaround would be to directly call the same function like
import react from 'react';
function mycomponent() {
const forceupdate = mycomponent();
return (
<div>
<button onclick={forceupdate}>
click to re-render
</button>
</div>
);
}
but this will break if you were passing some prop to it. in my case i just passed the same props which i received to rerender function.
score:1
if you already have a state inside the function component and you don't want to alter it and requires a re-render you could fake a state update which will, in turn, re-render the component
const [items,setitems] = usestate({
name:'your name',
status: 'idle'
})
const rerender = () =>{
setitems((state) => [...state])
}
this will keep the state as it was and will make react into thinking the state has been updated
score:3
best approach - no excess variables re-created on each render:
const forceupdatereducer = (i) => i + 1
export const useforceupdate = () => {
const [, forceupdate] = usereducer(forceupdatereducer, 0)
return forceupdate
}
usage:
const forceupdate = useforceupdate()
forceupdate()
score:8
simplest way 👌
if you want to force a re-render, add a dummy state you can change to initiate a re-render.
const [rerender, setrerender] = usestate(false);
...
setrerender(!rerender); //whenever you want to re-render
and this will ensure a re-render, and you can call setrerender(!rerender)
anywhere, whenever you want :)
score:9
i used a third party library called use-force-update to force render my react functional components. worked like charm. just use import the package in your project and use like this.
import useforceupdate from 'use-force-update';
const mybutton = () => {
const forceupdate = useforceupdate();
const handleclick = () => {
alert('i will re-render now.');
forceupdate();
};
return <button onclick={handleclick} />;
};
score:59
official faq ( https://reactjs.org/docs/hooks-faq.html#is-there-something-like-forceupdate ) now recommends this way if you really need to do it:
const [ignored, forceupdate] = usereducer(x => x + 1, 0);
function handleclick() {
forceupdate();
}
score:67
update react v16.8 (16 feb 2019 realease)
since react 16.8 released with hooks, function components have the ability to hold persistent state
. with that ability you can now mimic a forceupdate
:
function app() {
const [, updatestate] = react.usestate();
const forceupdate = react.usecallback(() => updatestate({}), []);
console.log("render");
return (
<div>
<button onclick={forceupdate}>force render</button>
</div>
);
}
const rootelement = document.getelementbyid("root");
reactdom.render(<app />, rootelement);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.1/umd/react-dom.production.min.js"></script>
<div id="root"/>
note that this approach should be re-considered and in most cases when you need to force an update you probably doing something wrong.
before react 16.8.0
no you can't, state-less function components are just normal functions
that returns jsx
, you don't have any access to the react life cycle methods as you are not extending from the react.component
.
think of function-component as the render
method part of the class components.
Source: stackoverflow.com
Related Query
- React - How to force a function component to render?
- React - How do i force child components to re render when parent state component changes?
- How to render react component inside function in another component?
- How can I return a React Component from a function and render it onClick?
- How to render react component after function call?
- How can a function correctly accept a React component and its props as arguments in TypeScript and render this component?
- how to import a function from one component react to another component to render it?
- How to use data of an Async function inside a functional component to render HTML in React
- How to call a function method in a component class render method? getting Uncaught TypeError: Cannot read property 'value' of null in React
- React, how to access the DOM element in my render function from the same component
- How to specify function parameters for React component callback with TypeScript?
- Return DOM element in render function of React component
- How to render React Component into itself, in a recursive way
- React hooks: call component as function vs render as element
- how to render a react component using ReactDOM Render
- Reactjs How to insert react component into string and then render
- How to pass the match when using render in Route component from react router (v4)
- How to get value from a react function within a react component
- how to access vairables outside of map function in js and jsx in a React component
- How to use jest.spyOn with React function component using Typescript
- How to wait for complete render of React component in Mocha using Enzyme?
- How to get parent component name in React function component
- How to render a React component (ES6 API) directly using ReactDOM?
- How to stop re render child component when any state changed in react js?
- How does React know if a function component is a React component?
- How to Get: Component Width After Render in React
- React: How to add onChange functionality inside of Function component using React Hooks? Need onClick event from a checkbox to influence input state
- How to call a component function on other component, but from the other component ? React
- use of variable inside render function of react component
- How to not use setState inside render function in React
More Query from same tag
- Material UI Tooltip does not appear when rendered inside of a custom Modal component
- Missing Something Sending Prop In Link In React
- CSS Word Wrap not applying to a react Typewriter plugin and more issues
- 'Undefined' when attempting to pass MaterialUI theme props to styled components
- How react-dom identify the correct HTML file?
- Simple tabs component in ReactJS
- React conditionally opening different divs
- How to make only text of react bootstrap table header clickable
- Forward ref through React Router's withRouter HOC
- How do I dynamically generate an element with a tag name based on a prop?
- Firebase library for Node.js breaks when using 'babel' loader. Specifically: "Uncaught TypeError: Cannot read property 'navigator' of undefined"
- Is it necessary to save everything in redux state?
- React.js with OpenWeatherMap, getting weathers.map is not a function
- Why is child component not rerendering in React?
- ReactDOM Hydrate Renders HTML as Text on Client Page
- NextJS: Error serializing `.data.data` returned from `getServerSideProps`
- Testing interactions in stateless react component using shalllow rendering
- Javascript function to get 3 objects based by props
- Why is my zebra-striping CSS not applying to my table rows?
- Properly filter an array inside other array in reactjs
- How to get the row index of a clicked cell in react-table?
- How to import 2,3 object from another file in reactJS
- Injecting into nested components with mobx-react
- How to set an Array in a nested objects React hook
- React: How to build a string with state values?
- Is it possible to use same function to setstate on different objects
- Yup schema generator for form array and nested form groups using Formik, Material-UI - React
- functions not calling correctly in onclick
- Best way to use conditional for useContext in React?
- How to change React js environment property file (.env) at runtime