React Hooks - How to avoid redeclaring functions on every render - reactjs

On a react class I would write something like this
class Myclass extends React.Component {
handleUpdate = info => {
//do the update
}
render() {
return (
<SomeMarkup>
<SomeComponent onUpdate={this.handleUpdate} />
</SomeMarkup>
)
}
}
If using a function I could just write the following
function MyFunction() {
function handleUpdate(info) {
// do the update
}
return (
<SomeMarkup>
<SomeComponent onUpdate={handleUpdate} />
</SomeMarkup>
)
}
...but with that I'd be redeclaring a function on every render. Is there any sort of trick that would memoize the handler function between renders? Or should I just move the handler out of the render scope? (Moving it out of the render scope requires me that I explicitly pass more parameters since I wont directly have access to the function scope.)

This is exactly the scenario that useCallback is for. The function still gets declared every time with useCallback, but the function returned is memoized so that if it is passed as a property to children, the children will receive a consistent function unless it has to change due to dependencies changing.
Please see my recent related answer here that demonstrates in detail how useCallback works:
Trouble with simple example of React Hooks useCallback
Here's another related answer: React Hooks useCallback causes child to re-render

Related

React: Modify Parent State While Child Renders

Hooks are usually much nicer than classes, so I'm trying to pass down the ability to set a parent's state in a child of that parent using hooks. Specifically, I'm doing something like this:
class Parent extends Component {
render = () => {
return <>
<Child useRegisterFoo={foo => {...;this.setState(foo);...;}} />
{ renderBasedOnRegister() }
</>
}
}
The goal is to be able to define the child like this:
const Child = ({useRegisterFoo}) => {
useRegisterFoo(1);
useRegisterFoo(2);
}
I will define many such children, and thus having such a simple useRegisterFoo to register a particular property of the child would be really useful.
The problem is that react complains if it's done this way, understandably, as I'm modifying the state of the parent while the parent is being rendered. Specifically it says:
Warning: Cannot update during an existing state transition (such as within `render`). Render methods should be a pure function of props and state.
What's a better approach at this problem? My main goal is to make the API from the perspective of the child as convenient as possible.
You are invoking the callbacks directly in the function body. This is an unintentional side-effect and shouldn't be done. Even in function components you still need to work with the component lifecycle.
Warning: Cannot update during an existing state transition (such as
within render). Render methods should be a pure function of props
and state.
The entire body of a function component is the "render" function. Use the useEffect hook to invoke these passed callbacks, or conditionally call them as part of an event handler.
Example:
Use an useEffect hook with an empty dependency array to trigger the effect only once when the component mounts.
const Child = ({useRegisterFoo}) => {
useEffect(() => {
useRegisterFoo(1);
useRegisterFoo(2);
}, []); // <-- empty dependency, effect triggered once on mount
...
}

React: How to pass state to child component and call function in child to use this state

I am implementing a component in functional components where there are several other child components in it passing data to each other. I need to pass data from parent to child component and call some function there to use it.
In class componenets we use componentdidupdate but could not understand how to do in functional component.
One idea is to use useEffect hook but could not do with it.
Im going to take a stab here, because we dont have context or code to go with.
useEffect accepts a dependency array to which it will react when a value or object reference changes
const ChildComponent = (props) => {
const {
valuePassedFromParent
} = props;
const actionFunction = (value) => {
//perform some tasks with value passed from parent when it changes
}
//this is similar to componentDidUpdate, but it reacts to changes in valuePassedFromParent though props since its in the useEffect dependency array
useEffect(() => {
//do something with valuePassedFromParent
actionFunction(valuePassedFromParent);
},[valuePassedFromParent]);
return (
<div>
</div>
)
}
You cas use useEffect to reproduce the behavior of componentdidupdate like this :
const [myState,setMyState] = useState();
useEffect(() => {
...
},[myState]);
The function use effect will run every time myState will be updated, like componentdiduptate would have do.
In your case, the state is given by the parent component if I understand well, so just replace the myState in the array dependency by the state given through the prop of your child component.

Need a clearer explanation how to avoid infinite re-rendering with React hooks

Not so fluent with React hooks, used plenty of class components before, hope you'll be forgiving.
The current code causes infinite re-rendering, and I think I understand why - the entire function body is being called on re-render.
const NavTabs = () => {
const classes = useStyles();
const [categories, setCategories] = React.useState();
const axiosPromise = getRequest(consts.categoriesURL);
axiosPromise.then(data => {
setCategories(data.value);
})
return (
<div className={classes.root}>
<AppBar position="static">
</AppBar>
{categories && <DynamicTabs categories={categories}/>}
</div>
);
}
I guess I could do something like if (!categories) { const axiosPromise [...] and so forth, i.e. do the http request only if categories haven't been populated yet. I guess this could also be solved by useEffect? Or wrapping the hook in an internal function?
I guess my real question is - why is React re-rendering the entire function body? Shouldn't it re-render only the return function? And then what is the point of using hooks that will be re-run on every render?
Compared to class components - shouldn't the code in the function body be equivalent to the constructor code in class components, and the return function - equivalent to the render method?
I guess I could do something like if (!categories) { const axiosPromise [...] and so forth, i.e. do the http request only if categories haven't been populated yet. I guess this could also be solved by useEffect? Or wrapping the hook in an internal function?
Yes, useEffect is the way to go here. Making a request and setting the result as state are side effects should only be run once in your case. We can achieve that easily with useEffect.
I guess my real question is - why is React re-rendering the entire function body? Shouldn't it re-render only the return function? And then what is the point of using hooks that will be re-run on every render?
React has no way to split a js function and only re-render the return. The function is atomic and must be completed. That is what hooks are for. React controls when hooks are ran so it can do fun stuff like batch state updates, ignore outdated effects and prioritise high priority work like animations.
Compared to class components - shouldn't the code in the function body be equivalent to the constructor code in class components, and the return function - equivalent to the render method?
The functional component is equivalent to the render method of a class component. They are called in a similar way. All the other lifecycle methods are replaced by hooks.
I recommend the react docs are great place to start and Dan Abramov has a great deep dive on hooks.
Yes, getRequest is being invoked each render cycle which sets some state and triggers a rerender. Placing it in an effect hook with a dependency array is likely the best solution. What dependencies you define will dictate when getRequest can be invoked.
Why is React re-rendering the entire function body?
The entire function body needs to run in order to determine the return value.
And then what is the point of using hooks that will be re-run on every render?
Hooks are run on every render, in the same order they are defined, but depending on dependencies may not invoke a callback. Hooks are what give functional components so much viability and sense of component lifecycle, to nearly be equivalent to class-based components in functionality. In most cases, you can completely convert a class-based component to a functional one and not drop any functionality.
Compared to class components - shouldn't the code in the function body be equivalent to the constructor code in class components, and the return function - equivalent to the render method?
It is more accurate to think of the entire functional components definition as the class-based render function, which can contain some logic and returns computed JSX to render to the DOM.
Example Solution:
const NavTabs = () => {
const classes = useStyles();
const [categories, setCategories] = React.useState(); // <-- no initial state!
useEffect(() => {
getRequest(consts.categoriesURL).then(data => {
setCategories(data.value); // <-- will update state and trigger render
});
}, []); // <-- empty dependency is run once on component mount
return (
<div className={classes.root}>
<AppBar position="static">
</AppBar>
{categories && <DynamicTabs categories={categories}/>}
</div>
);
}
To answer "why react is running the entire function" the answer is that javascript functions work that way: you always have to run the whole thing, they don't stop in the middle*. I understand what you are thinking here, if you are used to class components: don't I have a constructor section and a render section? and the answer is: not really if you are using function components. You only have render. But hooks are magic, and they let you pretend to have two parts.
Hooks know when they are called, and assuming you always call them in the same order, the can keep track of state outside the render function. so the way the work is sorta like this:
React detects a function component and creates or re-uses an existing rendering context for that component. This is where the hook information lives.
React calls your function component and it starts running.
You call hooks within your function component. These check what the current rendering context is, and save/get relevant information from that context. In a sense the rendering context is a "global" variable.
You do whatever else you want within the function, and eventually return a component tree (JSX) or null.
react then (eventually) updates the DOM to match what you returned, and saves the changes to the rendering context, so the next time render is called, it can re-use the context.
The magic is that the rendering context can do fancy things with hooks, like only run them once, always return the same value from a hook, or any other number of things. But in a sense, the component "class" becomes the react-internal rendering context that hooks know how to access.
Here is an example of the useState hook implemented in a class component: (You wouldn't ever need to do this, but it's an example of how hooks work).
class FakeHook extends React.Component {
constructor(...args) {
super(...args)
this.state = {}
this.useStateCalls = 0
}
useState(defaultValue){
const currentRenderContext = this.state
let value = defaultValue
const currentStateKey = `useState${this.useStateCalls}`
if (currentStateKey in currentRenderContext) value = currentRenderContext[currentStateKey]
this.useStateCalls++
return[value, (newValue) => this.setState({[currentStateKey]: newValue})]
}
render(){
this.useStateCalls = 0
let [fooState, setFoo] = this.useState("foo default")
let [barState, setBar] = this.useState("bar default")
return(
<dl>
<dt>Foo state</dt>
<dd>
<strong>Value:</strong>
<div>{fooState}</div>
<button onClick={(event) => {event.preventDefault(); setFoo(`foo updated at ${new Date().toLocaleString()}`)}}>Update Foo</button>
</dd>
<dt>Bar state</dt>
<dd>
<strong>Value:</strong>
<div>{barState}</div>
<button onClick={(event) => {event.preventDefault(); setBar(`bar updated at ${new Date().toLocaleString()}`)}}>Update Bar</button>
</dd>
<dt>Render context state:</dt>
<dd><pre>{JSON.stringify(this.state)}</pre></dd>
</dl>
)
}
}
ReactDOM.render(<FakeHook/>, document.getElementById('main'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<main id=main>loading or error occurred...</main>
Notice that state is stored based on the order the hook is called inside render. In real hooks, the render context is stored somewhere other than this.state, but hooks know how to get it, and you don't really care. Also, this is just an example, real hooks work slightly differently, but the concept is the same.
*: async functions and generators don't run all at once, and instead return a special object that lets the function run in multiple steps, waiting or pausing on await or yield.

Can we access props passed to the component in a custom function

this may sound silly but I can't find a guide to this.
what I'm trying to do is changing a variable named update in parent.
and in the parent DOM do :
<Child update={this.state.update} />
and in the child instead of picking it up between render and return (with const {update} = this.props) and only being able to use it in the DOM, I'd like to pick it up in the section between the constructor and render and use it in a function there.
You can access the props to the component anywhere in the component whether it be the constructor, lifecycle functions, render or custom functions.
The only thing that you need to know is that constructor, lifecycle methods and render function are already have binding to the context of the React component, but for custom function you need to add binding yourself. Binding can be done in the constructor or by declaring the functions as arrow functions.
Check this answer on why you need to bind custom functions: Why do we need to bind function and eventHandlers in React and what is the difference between the different binding methods
For your case
<Child update={this.state.update} />
where Child could be
class Child extends React.Component {
componentDidMount() {
const {update} = this.update || {};
console.log(update);
this.somefunc();
}
somefunc = () = {
const {update} = this.update || {}; //After function is binded, you can do the same thing here too
console.log(update);
}
}
React has a lifecycle of functions called on a component: https://reactjs.org/docs/react-component.html
On startup of component you can use componentDidMount()
if you want to change state based on props change use: componentWillReceiveProps()
Otherwise if you want the result of that function to use as data for in your view (but just manipulated). Than make a seperate function also called: computed property of computed function. (because the result is computed based on current state/props). React will make sure you don't re-render/compute unnecessary.

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

I have an external (to the component), observable object that I want to listen for changes on. When the object is updated it emits change events, and then I want to rerender the component when any change is detected.
With a top-level React.render this has been possible, but within a component it doesn't work (which makes some sense since the render method just returns an object).
Here's a code example:
export default class MyComponent extends React.Component {
handleButtonClick() {
this.render();
}
render() {
return (
<div>
{Math.random()}
<button onClick={this.handleButtonClick.bind(this)}>
Click me
</button>
</div>
)
}
}
Clicking the button internally calls this.render(), but that's not what actually causes the rendering to happen (you can see this in action because the text created by {Math.random()} doesn't change). However, if I simply call this.setState() instead of this.render(), it works fine.
So I guess my question is: do React components need to have state in order to rerender? Is there a way to force the component to update on demand without changing the state?
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.
forceUpdate should be avoided because it deviates from a React mindset. The React docs cite an example of when forceUpdate might be used:
By default, when your component's state or props change, your component will re-render. However, if these change implicitly (eg: data deep within an object changes without changing the object itself) or if your render() method depends on some other data, you can tell React that it needs to re-run render() by calling forceUpdate().
However, I'd like to propose the idea that even with deeply nested objects, forceUpdate is unnecessary. By using an immutable data source tracking changes becomes cheap; a change will always result in a new object so we only need to check if the reference to the object has changed. You can use the library Immutable JS to implement immutable data objects into your app.
Normally you should try to avoid all uses of forceUpdate() and only read from this.props and this.state in render(). This makes your component "pure" and your application much simpler and more efficient.forceUpdate()
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() });
I want to note that this will replace the element that the key is changing on. An example of where this could be useful is when you have a file input field that you would like to reset after an image upload.
While the true answer to the OP's question would be forceUpdate() I have found this solution helpful in different situations. I also want to note that if you find yourself using forceUpdate you may want to review your code and see if there is another way to do things.
NOTE 1-9-2019:
The above (changing the key) will completely replace the element. If you find yourself updating the key to make changes happen you probably have an issue somewhere else in your code. Using Math.random() in key will re-create the element with each render. I would NOT recommend updating the key like this as react uses the key to determine the best way to re-render things.
In 2021 and 2022, this is the official way to forceUpdate a React Functional Component.
const [, forceUpdate] = useReducer(x => x + 1, 0);
function handleClick() {
forceUpdate();
}
I know the OP is for a class component. But the question was asked in 2015 and now that hooks are available, many may search for forceUpdate in functional components. This little bit is for them.
Edit 18th Apr 2022
It's usually bad practice to force update your components.
A few reasons that can cause the need to use force updates.
Not using state variables where you have to - local, redux, context.
The field from the state object you are trying to access and expecting to update/change is too deeply nested in objects or arrays. Even Redux advises to maintain flat objects or arrays. If only one field value changes in a complex object, React may not figure out that the state object has changed, thus it does not update the component. Keep your state flat and simple.
The key on your list items, as mentioned in another answer. In fact, this can cause other unexpected behaviors as well. I've seen lists where items are repeatedly rendered (duplicates) because the keys aren't identical or the keys are just missing altogether. Always request the backend team to send unique ids everywhere possible! Avoid using array indexes for keys. Do not try to create unique ids on the front-end by using nanoid, uuid or random. Because ids created using above methods change each time the component updates (keys provided to a list need to be static and the same on each render). Creating unique ids is usually a backend concern. Try your best to not bring that requirement to the front-end. The front-end's responsibility is only to paint what data the backend returns and not create data on the fly.
If your useEffect, useCallback dependency arrays do not have the proper values set. Use ESLint to help you with this one! Also, this is one of the biggest causes for memory leaks in React. Clean up your state and event listeners in the return callback to avoid memory leaks. Because such memory leaks are awfully difficult to debug.
Always keep an eye on the console. It's your best friend at work. Solving warning and errors that show up in the console can fix a whole lot of nasty things - bugs and issues that you aren't even aware off.
A few things I can remember that I did wrong. In case it helps..
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.
forceUpdate()
Calling forceUpdate() will cause render() to be called on the component, skipping shouldComponentUpdate(). more...
setState()
setState() will always trigger a re-render unless conditional rendering logic is implemented in shouldComponentUpdate(). more...
forceUpdate() can be called from within your component by this.forceUpdate()
Hooks: How can I force component to re-render with hooks in React?
BTW: Are you mutating state or your nested properties don't propagate?
How to update nested state properties in React
Sandbox
I Avoided forceUpdate by doing following
WRONG WAY : do not use index as key
this.state.rows.map((item, index) =>
<MyComponent cell={item} key={index} />
)
CORRECT WAY : Use data id as key, it can be some guid etc
this.state.rows.map((item) =>
<MyComponent item={item} key={item.id} />
)
so by doing such code improvement your component will be UNIQUE and render naturally
When you want two React components to communicate, which are not bound by a relationship (parent-child), it is advisable to use Flux or similar architectures.
What you want to do is to listen for changes of the observable component store, which holds the model and its interface, and saving the data that causes the render to change as state in MyComponent. When the store pushes the new data, you change the state of your component, which automatically triggers the render.
Normally you should try to avoid using forceUpdate() . From the documentation:
Normally you should try to avoid all uses of forceUpdate() and only read from this.props and this.state in render(). This makes your application much simpler and more efficient
use hooks or HOC take your pick
Using hooks or the HOC (higher order component) pattern, you can have automatic updates when your stores change. This is a very light-weight approach without a framework.
useStore Hooks way to handle store updates
interface ISimpleStore {
on: (ev: string, fn: () => void) => void;
off: (ev: string, fn: () => void) => void;
}
export default function useStore<T extends ISimpleStore>(store: T) {
const [storeState, setStoreState] = useState({store});
useEffect(() => {
const onChange = () => {
setStoreState({store});
}
store.on('change', onChange);
return () => {
store.off('change', onChange);
}
}, []);
return storeState.store;
}
withStores HOC handle store updates
export default function (...stores: SimpleStore[]) {
return function (WrappedComponent: React.ComponentType<any>) {
return class WithStore extends PureComponent<{}, {lastUpdated: number}> {
constructor(props: React.ComponentProps<any>) {
super(props);
this.state = {
lastUpdated: Date.now(),
};
this.stores = stores;
}
private stores?: SimpleStore[];
private onChange = () => {
this.setState({lastUpdated: Date.now()});
};
componentDidMount = () => {
this.stores &&
this.stores.forEach((store) => {
// each store has a common change event to subscribe to
store.on('change', this.onChange);
});
};
componentWillUnmount = () => {
this.stores &&
this.stores.forEach((store) => {
store.off('change', this.onChange);
});
};
render() {
return (
<WrappedComponent
lastUpdated={this.state.lastUpdated}
{...this.props}
/>
);
}
};
};
}
SimpleStore class
import AsyncStorage from '#react-native-community/async-storage';
import ee, {Emitter} from 'event-emitter';
interface SimpleStoreArgs {
key?: string;
defaultState?: {[key: string]: any};
}
export default class SimpleStore {
constructor({key, defaultState}: SimpleStoreArgs) {
if (key) {
this.key = key;
// hydrate here if you want w/ localState or AsyncStorage
}
if (defaultState) {
this._state = {...defaultState, loaded: false};
} else {
this._state = {loaded: true};
}
}
protected key: string = '';
protected _state: {[key: string]: any} = {};
protected eventEmitter: Emitter = ee({});
public setState(newState: {[key: string]: any}) {
this._state = {...this._state, ...newState};
this.eventEmitter.emit('change');
if (this.key) {
// store on client w/ localState or AsyncStorage
}
}
public get state() {
return this._state;
}
public on(ev: string, fn:() => void) {
this.eventEmitter.on(ev, fn);
}
public off(ev: string, fn:() => void) {
this.eventEmitter.off(ev, fn);
}
public get loaded(): boolean {
return !!this._state.loaded;
}
}
How to Use
In the case of hooks:
// use inside function like so
const someState = useStore(myStore);
someState.myProp = 'something';
In the case of HOC:
// inside your code get/set your store and stuff just updates
const val = myStore.myProp;
myOtherStore.myProp = 'something';
// return your wrapped component like so
export default withStores(myStore)(MyComponent);
MAKE SURE
To export your stores as a singleton to get the benefit of global change like so:
class MyStore extends SimpleStore {
public get someProp() {
return this._state.someProp || '';
}
public set someProp(value: string) {
this.setState({...this._state, someProp: value});
}
}
// this is a singleton
const myStore = new MyStore();
export {myStore};
This approach is pretty simple and works for me. I also work in large teams and use Redux and MobX and find those to be good as well but just a lot of boilerplate. I just personally like my own approach because I always hated a lot of code for something that can be simple when you need it to be.
So I guess my question is: do React components need to have state in
order to rerender? Is there a way to force the component to update on
demand without changing the state?
The other answers have tried to illustrate how you could, but the point is that you shouldn't. Even the hacky solution of changing the key misses the point. The power of React is giving up control of manually managing when something should render, and instead just concerning yourself with how something should map on inputs. Then supply stream of inputs.
If you need to manually force re-render, you're almost certainly not doing something right.
There are a few ways to rerender your component:
The simplest solution is to use forceUpdate() method:
this.forceUpdate()
One more solution is to create not used key in the state(nonUsedKey)
and call setState function with update of this nonUsedKey:
this.setState({ nonUsedKey: Date.now() } );
Or rewrite all current state:
this.setState(this.state);
Props changing also provides component rerender.
For completeness, you can also achieve this in functional components:
const [, updateState] = useState();
const forceUpdate = useCallback(() => updateState({}), []);
// ...
forceUpdate();
Or, as a reusable hook:
const useForceUpdate = () => {
const [, updateState] = useState();
return useCallback(() => updateState({}), []);
}
// const forceUpdate = useForceUpdate();
See: https://stackoverflow.com/a/53215514/2692307
Please note that using a force-update mechanism is still bad practice as it goes against the react mentality, so it should still be avoided if possible.
You could do it a couple of ways:
1. Use the forceUpdate() method:
There are some glitches that may happen when using the forceUpdate() method. One example is that it ignores the shouldComponentUpdate() method and will re-render the view regardless of whether shouldComponentUpdate() returns false. Because of this using forceUpdate() should be avoided when at all possible.
2. Passing this.state to the setState() method
The following line of code overcomes the problem with the previous example:
this.setState(this.state);
Really all this is doing is overwriting the current state with the current state which triggers a re-rendering. This still isn't necessarily the best way to do things, but it does overcome some of the glitches you might encounter using the forceUpdate() method.
We can use this.forceUpdate() as below.
class MyComponent extends React.Component {
handleButtonClick = ()=>{
this.forceUpdate();
}
render() {
return (
<div>
{Math.random()}
<button onClick={this.handleButtonClick}>
Click me
</button>
</div>
)
}
}
ReactDOM.render(<MyComponent /> , mountNode);
The Element 'Math.random' part in the DOM only gets updated even if you use the setState to re-render the component.
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().
The above code runs with setState as below.
class MyComponent extends React.Component {
handleButtonClick = ()=>{
this.setState({ });
}
render() {
return (
<div>
{Math.random()}
<button onClick={this.handleButtonClick}>
Click me
</button>
</div>
)
}
}
ReactDOM.render(<MyComponent /> , mountNode);
Just another reply to back-up the accepted answer :-)
React discourages the use of forceUpdate() because they generally have a very "this is the only way of doing it" approach toward functional programming. This is fine in many cases, but many React developers come with an OO-background, and with that approach, it's perfectly OK to listen to an observable object.
And if you do, you probably know you MUST re-render when the observable "fires", and as so, you SHOULD use forceUpdate() and it's actually a plus that shouldComponentUpdate() is NOT involved here.
Tools like MobX, that takes an OO-approach, is actually doing this underneath the surface (actually MobX calls render() directly)
forceUpdate(), but every time I've ever heard someone talk about it, it's been followed up with you should never use this.
forceUpdate(); method will work but it is advisable to use setState();
In order to accomplish what you are describing please try this.forceUpdate().
Another way is calling setState, AND preserve state:
this.setState(prevState=>({...prevState}));
I have found it best to avoid forceUpdate(). One way to force re-render is to add dependency of render() on a temporary external variable and change the value of that variable as and when needed.
Here's a code example:
class Example extends Component{
constructor(props){
this.state = {temp:0};
this.forceChange = this.forceChange.bind(this);
}
forceChange(){
this.setState(prevState => ({
temp: prevState.temp++
}));
}
render(){
return(
<div>{this.state.temp &&
<div>
... add code here ...
</div>}
</div>
)
}
}
Call this.forceChange() when you need to force re-render.
ES6 - I am including an example, which was helpful for me:
In a "short if statement" you can pass empty function like this:
isReady ? ()=>{} : onClick
This seems to be the shortest approach.
()=>{}
use useEffect as a mix of componentDidMount, componentDidUpdate, and componentWillUnmount, as stated in the React documentation.
To behave like componentDidMount, you would need to set your useEffect like this:
useEffect(() => console.log('mounted'), []);
The first argument is a callback that will be fired based on the second argument, which is an array of values. If any of the values in that second argument changed, the callback function you defined inside your useEffect will be fired.
In the example I'm showing, however, I'm passing an empty array as my second argument, and that will never be changed, so the callback function will be called once when the component mounts.
That kind of summarizes useEffect. If instead of an empty value, you have an argument, like:
useEffect(() => {
}, [props.lang]);
That means that every time props.lang changes, your callback function will be called. The useEffect will not rerender your component really, unless you're managing some state inside that callback function that could fire a re-render.
If you want to fire a re-render, your render function needs to have a state that you are updating in your useEffect.
For example, in here, the render function starts by showing English as the default language and in my use effect I change that language after 3 seconds, so the render is re-rendered and starts showing "spanish".
function App() {
const [lang, setLang] = useState("english");
useEffect(() => {
setTimeout(() => {
setLang("spanish");
}, 3000);
}, []);
return (
<div className="App">
<h1>Lang:</h1>
<p>{lang}</p>
</div>
);
}
You can use forceUpdate() for more details check (forceUpdate()).

Resources