@RomanSS

Возможно ли застопорить удаление компонента в react?

Интересует вопрос, как перед удалением компонента можно выполнить определенную функцию которая будет производить какие-то вычисления и так же работать над DOM и после полного выполенения только удалить его?
В ректе есть addon react-addons-css-transition-group который решает часть моих проблем заточенный как раз для выполнения задержки перед удалением, на время выполнение css анимации, но как быть если время выполнения не известно?
Есть еще react-motion тоже хороший модуль для анимации, но как работать с css классами там не понимаю там все на style заточено, или не разобрался просто.

Может как-то проще можно застопорить удаление из DOM?
Хочется сделать чтобы при удалении компонента изменяя пропсы (param=true или param=false)
{param?<Component>:null}
Компонент не удалялся из DOM и с ним можно было работать, выполнять какие-то функции и только когда моя функция возвращает true он удалял его из dom? Так как время выполнения функций может быть разной мне react-addons-css-transition-group не совсем подходит.

Может уже есть что-то похожее для решения таких задач?
  • Вопрос задан
  • 457 просмотров
Пригласить эксперта
Ответы на вопрос 1
Можно использовать тот факт, что дочерние компоненты в реакте (children) передаются просто как props. Поэтому можно предварительно сохранять их в state (в конструкторе) и затем, при каждом обновлении компонента, в методе componentWillReceiveProps смотреть какие children были удалены и вызывать для них какой-нибудь метод (назовем его doDefferedUnmount). Пускай этот метод возвращает promise и когда promise выполнится (resolve\reject - не важно) - удалять этот children из нашего буфера в state. При этом рендерить мы будем не реальные props.children, а дочерние компоненты из нашего внутреннего буфера в state. Также нам понадобятся ссылки (ref) на элементы (которые уже отрендерены реактом) так как нам нужно будет вызвать метод doDefferedUnmount. А он должен вызываться только для инстансов (элементов, а не компонентов: компонент - это класс).

// Я удалил все лишнее
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>
    )
  }
}


Рабочий пример кода - https://jsfiddle.net/jwm6k66c/1884/ . Элементы удаляются через 200мс после нажатия. Но я правда не знаю зачем вам это надо, так как при этом никак нельзя адекватно сделать функционал :
Компонент не удалялся из DOM и с ним можно было работать, выполнять какие-то функции и только когда моя функция возвращает true он удалял его из dom


Так как это не react-way. Вы мыслите другими подходами и библиотеками. В реакте вы берете redux (flux/...) и храните данные в хранилище (store), если вам нужно удалить какие-то данные (а объекты в DOM - это отображение данных) - отправляете запрос на сервер и в случае успеха диспатчите экшен (действие) на удаление данных из хранилища... и на следующем рендере нужные элементы удалятся, либо можно будет вывести сообщение об ошибке.


PS Пример кода я привел только для ознакомления с возможностями react. Я крайне не рекомендую использовать его для того, о чем говорит автор вопроса!
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы
22 нояб. 2024, в 00:55
500 руб./за проект
21 нояб. 2024, в 23:30
300000 руб./за проект
21 нояб. 2024, в 22:21
3000 руб./в час