React - How to Force a Function Component to Render

How to force a functional React component to render?

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:

  1. A value, representing the current state.
  2. 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
// A function that increment the previous state like here
// is better than directly setting `setValue(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>
);
}

You can find a demo here.

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.

Can you force a React component to rerender without calling setState?

In class components, you can call this.forceUpdate() to force a rerender.

Documentation: https://facebook.github.io/react/docs/component-api.html

In function components, there's no equivalent of forceUpdate, but you can contrive a way to force updates with the useState hook.

How can I force a component to re-render with hooks in React?

This is possible with useState or useReducer, since useState uses useReducer internally:

const [, updateState] = React.useState();
const forceUpdate = React.useCallback(() => updateState({}), []);

forceUpdate isn't intended to be used under normal circumstances, only in testing or other outstanding cases. This situation may be addressed in a more conventional way.

setCount is an example of improperly used forceUpdate, setState is asynchronous for performance reasons and shouldn't be forced to be synchronous just because state updates weren't performed correctly. If a state relies on previously set state, this should be done with updater function,

If you need to set the state based on the previous state, read about the updater argument below.

<...>

Both state and props received by the updater function are guaranteed
to be up-to-date. The output of the updater is shallowly merged with
state.

setCount may not be an illustrative example because its purpose is unclear but this is the case for updater function:

setCount(){
this.setState(({count}) => ({ count: count + 1 }));
this.setState(({count2}) => ({ count2: count + 1 }));
this.setState(({count}) => ({ count2: count + 1 }));
}

This is translated 1:1 to hooks, with the exception that functions that are used as callbacks should better be memoized:

   const [state, setState] = useState({ count: 0, count2: 100 });

const setCount = useCallback(() => {
setState(({count}) => ({ count: count + 1 }));
setState(({count2}) => ({ count2: count + 1 }));
setState(({count}) => ({ count2: count + 1 }));
}, []);

Forcing a react functional component to trigger a rerender

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.

React function component renders Renders on focus

Changing state causes re-renders. You can use useRef to avoid this issue. You will get values in containerId.current and searchValue.current.

export default function App() {

const containerId = useRef();
const searchValue = useRef();

return (
<input
onInput={(e) => searchValue.current = e.currentTarget.value}
onFocus={(e) => containerId.current = e.currentTarget.id}
id={1}
/>
);

}


Related Topics



Leave a reply



Submit