R
R
RomanSS2017-01-19 17:37:39
React
RomanSS, 2017-01-19 17:37:39

Is it possible to stall the removal of a component in react?

I'm interested in the question of how, before deleting a component, it is possible to execute a certain function that will perform some calculations and also work on the DOM and, after complete execution, only delete it?
There is an addon in the react-addons-css-transition-group that solves some of my problems, sharpened just to perform a delay before deleting, for the duration of the css animation, but what if the execution time is not known?
There is also react-motion, which is also a good module for animation, but I don’t understand how to work with css classes there, everything is sharpened on style, or I simply didn’t figure it out.
Maybe somehow it is easier to stop the removal from the DOM?
I would like to make it so that when the component is removed, changing the props (param=true or param=false)
{param?<Component>:null}
The component was not removed from the DOM and it was possible to work with it, perform some functions, and only when my function returns true did it remove it from the dom? Since the execution time of functions can be different, react-addons-css-transition-group is not quite suitable for me.
Maybe already there is something similar for solving such problems?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
N
Nikita Gushchin, 2017-01-19
@iNikNik

You can use the fact that child components in react (children) are simply passed as props. Therefore, you can first save them in the state (in the constructor) and then, with each update of the component, in the componentWillReceiveProps method, look at which children have been removed and call some method for them (let's call it doDefferedUnmount). Let this method return a promise and when the promise is fulfilled (resolve \ reject - it doesn't matter) - remove this children from our buffer in state. In this case, we will not render real props.children, but child components from our internal buffer in state. We will also need references (ref) to elements (which are already rendered by React) since we will need to call the doDefferedUnmount method. And it should only be called for instances (elements, not components: a component is a class).

// Я удалил все лишнее
class DelayedContainer extends React.PureComponent {
  constructor(props, context) {
    super(props, context)
    
    this.chidrenRefs = {}
    this.state = {
      childrenStore: this.childrenArrToStore(React.Children.toArray(props.children))
    }
  }

  removeChidren = (key) => {
    const { childrenStore } = this.state
    
    this.chidrenRefs = _.omit(this.chidrenRefs, key)
    this.setState({
    	childrenStore: _.omit(childrenStore, key)
    })
  }

  handleChildRef = (node, key) => {
    this.chidrenRefs[key] = node
  }

  render() {
    const { childrenStore } = this.state
  
    return (
    	<div>
        {_.values(childrenStore).map(child => {
        	return React.cloneElement(child, { ref: node => this.handleChildRef(node, child.key) })
        })}
      </div>
    )
  }

// Компонент, который будем удалять с задержкой
// обратите внимание на метод doDefferedUnmount 
// именно его мы будем вызывать
class SomeItem  extends React.PureComponent {
  doDefferedUnmount = () => {
    console.log('doDefferedUnmount for ', this.props.word);
    return new Promise(resolve => setTimeout(resolve, 200))
  }

  handleClick = e => {
    const { id, onClick } = this.props
    return onClick && onClick(id, e)
  }

  render() {
    const { word } = this.props

    return (
    	<button type="button" onClick={this.handleClick}>{word}</button>
    )
  }
}

Working sample code - https://jsfiddle.net/jwm6k66c/1884/ . Items are removed 200ms after being clicked. But I really don’t know why you need it, since in this case it’s impossible to adequately make the functionality:
Since it's not react-way. You think in other approaches and libraries. In React, you take redux (flux/...) and store data in the store (store), if you need to delete some data (and objects in the DOM are a display of data) - send a request to the server and, if successful, dispatch the action (action) to delete data from the storage... and on the next render, the necessary elements will be deleted, or an error message can be displayed.
PS I gave a code example only to get acquainted with the capabilities of react. I highly recommend against using it for what the questioner is talking about!

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question