Перехватчик React, который запускается ПОСЛЕ обновления DOM - PullRequest
1 голос
/ 29 мая 2020

У меня есть приложение React, в котором я скрываю / показываю элемент, основанный на состоянии, и хочу выполнить некоторые вычисления с этим элементом DOM после изменения переменной состояния.

Я пробовал использовать useLayoutEffect , но он по-прежнему работает до DOM обновляется, поэтому мои расчеты бесполезны. Я неправильно понимаю useLayoutEffect? Я неправильно его использую?

Вот что у меня

const myComponent = () => {

  const elem = useRef()
  const [isElemVisible, setIElemVisible] = useState(false)

  useLayoutEffect(() => {
    // I want this to run AFTER the element is added/removed from the DOM
    // Instead this is run before the element is actually modified in the DOM (but the ref itself has changed)

    elem.current.getBoundingClientRect() // do something with this object if it exists
  }, [elem.current])


  return (
   <div id="base-element">
    { isElemVisible && (
      <div id="element" ref={elem}></div>
    )}
   </div>
  )
}

Ответы [ 2 ]

1 голос
/ 29 мая 2020

Вы можете попробовать передать функцию как ref и сделать что-нибудь в этой функции:

const myComponent = () => {

  // other component code

  const elemRef = useCallback((node) => {
    if (node !== null) {
      // do stuff here
    }
  }, [])


  return (
   <div id="base-element">
    { isElemVisible && (
      <div id="element" ref={elemRef}></div>
    )}
   </div>
  )
}

Посмотрите этот https://reactjs.org/docs/hooks-faq.html#how -can-i-measure-a-dom-node

0 голосов
/ 29 мая 2020

Простое решение - вручную проверить обновление состояния в ловушке useEffect:

const myComponent = () => {

  const elem = useRef()
  const [isElemVisible, setIElemVisible] = useState(false)

  useEffect(() => {
   if (isElemVisible) {
     // Assuming UI has updated:
     elem.current.getBoundingClientRect() // do something with this object
   }

  }, [isElemVisible])


  return (
   <div id="base-element">
    { isElemVisible && (
      <div id="element" ref={elem}></div>
    )}
   </div>
  )
}
...