I have a question regarding "one time actions" in react components. Imagine for example I want to scroll some element to certain position, or reset the internal react state.
So far I've been doing this by using a combination of a boolean flag (e.g. doAction: true
) and an update action (e.g. setDoActionBackToFalse
), but this seems too complex. Does anyone have any nice solution to this?
Note: The action can actually happen multiple times during the lifetime of the component but each time it has to be specifically triggered and happen only once (not keep happening on every rerender). E.g. scroll to every newly added item in scrollpane.
I created small fiddle to make the problem more obvious: https://jsfiddle.net/martinkadlec/et74rkLk/1/ This uses the boolean flag approach.
Use the useEffect hook to only call a function once in React. When the useEffect hook is passed an empty dependencies array, it is only run when the component mounts. This is the preferred approach when you have to fetch data when the component mounts.
From the previous question, we found out that componentDidMount doesn't have the same behavior with useEffect hook, because componentDidMount invoked synchronously before the browser paints the screen, while useEffect is invoked asynchronously after the browser has already painted the screen.
This principle tells us that a class or a function should have a single responsibility. React applications consist of components. If we visualized those components, we would see a component tree as shown below. Component tree.
3, getDerivedStateFromProps() was added as a static lifecycle method to prevent unsafe accesses of instance properties. getDerivedStateFromProps() is bound with null value when it is called by React. Therefore, when accessing this in the static lifecycle method, a TypeError exception is thrown. if (nextProps.
It has been some time since I asked this question and since then I found that as long as the "one time action" doesn't actually rerender the component, but instead just modifies some browser state (e.g. focus, scroll position, etc.) people generally tend to solve this by having a class method and calling it from the parent component using refs.
To illustrate on the focus example:
class Input extends React.Component {
inputElRef = React.createRef();
focus = () => this.inputElRef.current.focus();
render() {
return (
<input ref={this.inputElRef} />
);
}
}
class Parent extends React.Component {
inputRef = React.createRef();
render() {
return (
<div>
<button onClick={() => this.inputRef.current.focus()}>Focus input</button>
<Input ref={this.inputRef} />
</div>
);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With