Как мы узнаем, когда значение React ref.current изменилось? - PullRequest
0 голосов
/ 24 апреля 2019

Обычно, с помощью реквизита, мы можем написать

componentDidUpdate(oldProps) {
  if (oldProps.foo !== this.props.foo) {
    console.log('foo prop changed')
  }
}

, чтобы обнаружить изменения реквизита.

Но если мы используем React.createRef(), как мы можем определить, когда ссылка измениласьк новому компоненту или элементу DOM?Документы по React ничего не упоминают.

Fe,

class Foo extends React.Component {
  someRef = React.createRef()

  componentDidUpdate(oldProps) {
    const refChanged = /* What do we put here? */

    if (refChanged) {
      console.log('new ref value:', this.someRef.current)
    }
  }

  render() {
    // ...
  }
}

Должны ли мы сами реализовывать что-то вроде старой ценности?

Fe,

class Foo extends React.Component {
  someRef = React.createRef()
  oldRef = {}

  componentDidMount() {
    this.oldRef.current = this.someRef.current
  }

  componentDidUpdate(oldProps) {
    const refChanged = this.oldRef.current !== this.someRef.current

    if (refChanged) {
      console.log('new ref value:', this.someRef.current)

      this.oldRef.current = this.someRef.current
    }
  }

  render() {
    // ...
  }
}

Это то, что мы должны делать?Я бы подумал, что React приготовил бы для этого какую-нибудь простую функцию.

1 Ответ

1 голос
/ 25 апреля 2019

componentDidUpdate вызывается при изменении состояния компонента или реквизита, поэтому он не обязательно будет вызываться при изменении ref, поскольку он может быть изменен по вашему усмотрению.

Если вы хотите проверить, изменился ли реф по сравнению с предыдущим рендером, вы можете оставить другой реф, который вы сверяете с реальным.

Пример

class App extends React.Component {
  prevRef = null;
  ref = React.createRef();
  state = {
    isVisible: true
  };

  componentDidMount() {
    this.prevRef = this.ref.current;

    setTimeout(() => {
      this.setState({ isVisible: false });
    }, 1000);
  }

  componentDidUpdate() {
    if (this.prevRef !== this.ref.current) {
      console.log("ref changed!");
    }

    this.prevRef = this.ref.current;
  }

  render() {
    return this.state.isVisible ? <div ref={this.ref}>Foo</div> : null;
  }
}

ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

<div id="root"></div>
...