Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

One time action in React Components

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.

like image 566
Martin Kadlec Avatar asked Mar 20 '17 10:03

Martin Kadlec


People also ask

How do you only do something once in React?

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.

What is difference between componentDidMount and useEffect?

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.

What is single responsibility principle in React?

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.

Why is getDerivedStateFromProps static?

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.


1 Answers

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>
     );
  }
}
like image 190
Martin Kadlec Avatar answered Nov 06 '22 23:11

Martin Kadlec