Можно ли извлечь экземпляр компонента из React Fiber?

До версии 16 React - то есть до введения волокон React - можно было взять элемент DOM и извлечь экземпляр компонента React следующим образом:

const getReactComponent = dom => {
  let found = false;
  const keys = Object.keys(dom);

  keys.forEach(key => {
    if (key.startsWith('__reactInternalInstance$')) {
      const compInternals = dom[key]._currentElement;
      const compWrapper = compInternals._owner;
      const comp = compWrapper._instance;
      found = comp;
    }
  });

  return found || null;
};

Это больше не работает для React v16, который использует новую реализацию Fiber. В частности, приведенный выше код выдает ошибку в строке const comparWrapper = compInternals._owner потому что нет _owner собственность больше. Таким образом, вы не можете также получить доступ к _instance,

Мой вопрос здесь заключается в том, как бы мы извлекли экземпляр из элемента DOM в реализации Fiber v16?

2 ответа

Вы можете попробовать функцию ниже (обновлена ​​для работы с React <16 и 16+):

window.FindReact = function(dom) {
    let key = Object.keys(dom).find(key=>key.startsWith("__reactInternalInstance$"));
    let internalInstance = dom[key];
    if (internalInstance == null) return null;

    if (internalInstance.return) { // react 16+
        return internalInstance._debugOwner
            ? internalInstance._debugOwner.stateNode
            : internalInstance.return.stateNode;
    } else { // react <16
        return internalInstance._currentElement._owner._instance;
    }
}

Применение:

var someElement = document.getElementById("someElement");
FindReact(someElement).setState({test1: test2});

React 17 немного отличается:

      function findReact(dom) {
    let key = Object.keys(dom).find(key => key.startsWith("__reactFiber$"));
    let internalInstance = dom[key];
    if (internalInstance == null) return "internalInstance is null: " + key;

    if (internalInstance.return) { // react 16+
        return internalInstance._debugOwner
            ? internalInstance._debugOwner.stateNode
           : internalInstance.return.stateNode;
    } else { // react <16
        return internalInstance._currentElement._owner._instance;
   }
}

domElement в этом — это tr с именем параметра данных поля, которое вы пытаетесь изменить:

      var domElement = ?.querySelectorAll('tr[data-param-name="<my field name>"]')
Другие вопросы по тегам