Actually, forceUpdate() is the only correct solution as setState() might not trigger a re-render if additional logic is implemented in shouldComponentUpdate() or when it simply returns false. setState() will always trigger a re-render unless conditional rendering logic is implemented in shouldComponentUpdate(). more... The simplest solution is to use forceUpdate() method: All the answers here are correct supplementing the question for understanding..as we know to re-render a component with out using setState({}) is by using the forceUpdate().
setNumbers([...old])
Changing the key of the element you want re-rendered will work. Set the key prop on your element via state and then when you want to update set state to have a new key.
<Element key={this.state.key} />
Then a change occurs and you reset the key
this.setState({
key: Math.random()
});
Method 1 (by changing props): If we pass the state of the parent component as a prop to the child and call setState on the parent, it will cause the re-render of the child component as its props are changed. In React, to re-render a class-based component with an updated state we generally use the setState() method. However, we can re-render a component in two different ways that are – Caution: Even though forceUpdate solves our problem but it is advised to use setState or changing props to re-render a component as forceUpdate method skips the proper lifecycle of rendering of a component. See this for detail.
The below code demonstrates the same.
import React, { Component } from "react";
class App extends Component {
constructor(props) {
super(props);
// Set initial state of parent
this.state = { category: "Coder" };
// Binding this keyword
this.updateState = this.updateState.bind(this);
}
updateState() {
// Changing state
this.setState({ category: "Geek" });
}
render() {
return (
<div>
<Child category={this.state.category} />
<button onClick={this.updateState}>Click me!</button>
</div>
);
}
}
class Child extends Component {
render() {
return (
<div>
<p>Hi {this.props.category}!</p>
</div>
);
}
}
export default App;
The below code demonstrates the use of forceUpdate by generating a random number between 1 and 10 by forcing re-render:
import React, { Component } from "react";
class App extends Component {
reRender = () => {
// force update
this.forceUpdate();
};
render() {
return (
<div>
<h2>Random Number Generator</h2>
<p>Your Number: {Math.floor(Math.random() * 10) + 1}</p>
<button onClick={this.reRender}>Generate!</button>
</div>
);
}
}
export default App;
In any user or system event, you can call the method this.forceUpdate(), which will cause render() to be called on the component, skipping shouldComponentUpdate(), and thus, forcing React to re-evaluate the Virtual DOM and DOM state. React will trigger the normal lifecycle methods for child components, including shouldComponentUpdate(), so we only can force the current component to be re-rendered Here, we use useCallback to memoize our forceUpdate function, thus keeping it constant throughout the component lifecycle and making it safe to be passed to child components as props.
Let’s build a simple component to demonstrate one common reason components aren’t rendering. We will build a simple app that will show a username, Juan
, and, after pressing a button, the name will change to Peter
.
Here is a demonstration of the app with the complete code. You probably noticed that after clicking the button, nothing happens, even though we changed our state on the button:
function changeUserName() {
user.name = "Peter";
setUser(user);
}
State, as described in the React documentation, should be treated as immutable.
So, how do we fix it? We could create a new object with the correct values as follows:
function changeUserName() {
setUser({
...user,
name: "Peter"
});
}
In this demo, I built a clock that has a major problem: the time doesn’t change after I first load the screen. Not a very useful clock, right?
Let’s take a look at the code responsible for calculating the current time:
let myTime;
function setMyTime() {
myTime = new Date();
setTimeout(() => {
setMyTime();
}, 1000);
}
setMyTime();
This demo doesn’t work because props are a reflection of state, so a standalone change in props won’t trigger a re-render. To fix it, we need a total rewrite.
Notice that we introduced state to manage myTime
and useEffect
to start and clear the timers to avoid bugs when the component re-renders. And it works!
const [myTime, setMyTime] = useState(new Date());
useEffect(() => {
var timerID = setInterval(() => tick(), 1000);
return () => clearInterval(timerID);
});
function tick() {
setMyTime(new Date());
}
If you are using class components in your code, you’re in luck. React provides an official API to force a re-render, and it’s straightforward to implement:
someMethod() {
// Force a render without state change...
this.forceUpdate();
}
If you need to re-render a React component, always update the components state and props. Try to avoid causing re-render with key prop, because it will add a bit more complexity. But There are odd use cases where this is needed. When the button gets clicked on it will update the <Child /> component, and cause it to run the render() lifecycle again. By changing the value of the key prop, it will make React unmount the component and re-mount it again, and go through the render() lifecycle.
Any time a React component state has changed, React has to run the render()
method.
class App extends React.Component {
componentDidMount() {
this.setState({});
}
render() {
console.log('render() method')
return <h1>Hi!</h1>;
}
}
In the example above I’m update the state when the component mounts.
You can also re-render a component on an event, such as a click event.
class App extends React.Component {
state = {
mssg: ""
};
handleClick = () => {
this.setState({ mssg: "Hi there!" });
};
render() {
console.log("render() method");
return (
<>
<button onClick={this.handleClick}>Say something</button>
<div>{this.state.mssg}</div>
</>
);
}
}
Both outputs will look like this:
render() method render() method
In the example above, <Child />
component does not have state, but it does have a custom prop that it accepts, message
.
Child component: render()
Child component: render()
This is a method that is highly discouraged. Always use props & state changes to cause a new render.
But nonetheless, here is how you can do it!
class App extends React.Component {
handleClick = () => {
// force a re-render
this.forceUpdate();
};
render() {
console.log('App component: render()')
return (
<>
<button onClick={this.handleClick}>Say something</button>
</>
);
}
}
React components automatically re-render whenever there is a change in their state or props. A simple update of the state, from anywhere in the code, causes all the User Interface (UI) elements to be re-rendered automatically. However, there may be cases where the render() method depends on some other data. After the initial mounting of components, a re-render will occur when: In the following example, the setState() method is called each time a character is entered into the text box. This causes re-rendering, which updates the text on the screen.
ourMethod() { // It simply sets the state to its current value this.setState({ state: this.state });};
import React, { Component } from 'react';
import 'bootstrap/dist/css/bootstrap.css';
class Greeting extends Component {
state = {
fullname: '',
}
stateChange = (f) => {
const {name, value} = f.target;
this.setState({
[name]: value,
});
}
render() {
return (
<div className="text-center">
<label htmlFor="fullname"> Full Name: </label>
<input type="text" name="fullname" onChange={this.stateChange} />
<div className="border border-primary py-3">
<h4> Greetings, {this.state.fullname}!</h4>
</div>
</div>
);
}
}
export default Greeting;
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(
<App />, document.getElementById('root'));
If the component already has state then you can update the state to its current value in a simple way: A React component automatically re-renders whenever there is a change in state or props, it only takes a simple state update from anywhere in the code to automatically re-render UI elements. However, you may see cases where rendering depends on other data. The forceUpdate() method of a component is called.
ourMethod() {
// It simply sets the state to its current value
this.setState({
state: this.state
});
};
Code:
import React, { Component } from 'react';
import 'bootstrap/dist/css/bootstrap.css';
class App extends React.Component{
builder(){
super();
this.forceUpdateHandler = this.forceUpdateHandler.bind(this);
};
forceUpdateHandler(){
this.forceUpdate();
};
render(){
return(
<div>
<button onClick= {this.forceUpdateHandler} >FORCE UPDATE</button>
<h4>Random Number : { Math.random() }</h4>
</div>
);
}
}
export defaultApp;
As we already saw before, React re-renders a component when you call the setState function to change the state (or the provided function from the useState hook in function components). It's important to change the state with the corresponding React functions. You can find the Codepen here. The first one, which I already gave away before, is React.memo. I already wrote a more in-depth article on this, but in summary, it's a function that prevents your React Hook components from rendering when the props don't change.
const App = () => {
const [message, setMessage] = React.useState('');
return (
<>
<Tile message={message} />
<Tile />
</>
);
};
this.props.user.name = 'Felix';
const Parent = () => {
const [user, setUser] = React.useState({ name: 'Felix' }); const handleInput = (e) => {
e.preventDefault();
setUser({ ...user, name: e.target.value, }); };
return (
<>
<input onChange={handleInput} value={user.name} />
<Child user={user} />
</>
);
};
const Child = ({ user }) => (
<h1>{user.name}</h1>
);
const [state, updateState] = React.useState();
const forceUpdate = React.useCallback(() => updateState({}), []);
const TileMemo = React.memo(({ children }) => { let updates = React.useRef(0);
return (
<div className="black-tile">
Memo
<Updates updates={updates.current++} />
{children}
</div>
);
});
By default, when your component's state or props change, your component will re-render. If your render() method depends on some other data, you can tell React that the component needs re-rendering by calling forceUpdate(). It is recommended to avoid all uses of forceUpdate() and only read from this.props and this.state in render(). Made by Michael Sakhniuk
component.forceUpdate(callback);
What exactly is Render in React, how can we force a class or functional component to re-render, and can it be done without calling setState? The short answer to the question of if you can force a React component to render (and without calling setState) is yes, you can. However, before we get to know how, let’s clear up a few important things first. In this article we covered what render is in React, what happens when state is updated, and how to force a re-render in class and functional components. For the final note, remember, if you ever think that you need to force a re-render, think again as there might be a better way. As you can see, whenever we need the component to be re-rendered, we just increment the counter. To be honest, we can go even further than that and create a custom hook for it.
Render – React calls the render function to gather output from createElement
functions
Reconciliation – New elements are compared against previously given elements and the virtual DOM is updated if there are differences
Commit – The real DOM is updated
Like I mentioned before, changing the state does not mean that the commit
phase will be executed, as there will be no need for it if there were no changes in the virtual DOM. As you can see on the example below, no matter how many times we click the button, the name
property is set to the same value, despite the fact that we call the setState
method.
// A simple example
class App extends Components {
state = {
name: ‘Thomas’
}
onClickHandler = () => {
this.setState({name: ‘Thomas’})
}
render() {
<div>
<p>My name is {this.state.name}</p><br/>
<button onClick={this.onClickHandler}>Click me</button>
</div>
}
}
If you are using a React class component then it is as easy as using this.forceUpdate()
function.
class App extends Components {
onClickHandler = () => {
this.forceUpdate()
}
render() {
<button onClick={this.onClickHandler}>Click me</button>
}
}
Just make sure that the this
context refers to the component instance. In the example below, this
refers to the scope of innerFunction
and not of the React component instance, and because of that it won’t work.
// This won’t work
class App extends Components {
onClickHandler = () => {
function innerFunction() {
this.forceUpdate()
}
innerFunction()
}
render() {
<button onClick={this.onClickHandler}>Click me</button>
}
}
In a function component there is no forceUpdate
method. However, we can mimic this functionality with the code below.
import React, {useState} from ‘react’
const App = props => {
const [count, setCount] = useState(0)
const onClickHandler = e = => {
setCount(prevCount => prevCount + 1)
}
return (
<button onClick={onClickHandler}>Click me</button>
)
}
import React, {useState} from ‘react’
const useForceUpdate = () => {
const [count, setCount] = useState(0)
const increment = () => setCount(prevCount => prevCount + 1)
return [increment, count]
}
const App = props => {
const [forceUpdate] = useForceUpdate()
const onClickHandler = e => {
forceUpdate()
}
return (
<button onClick={onClickHandler}>Click me</button>
)
}