A los efectos de la depuración en la consola, ¿hay algún mecanismo disponible en React para usar una instancia de elemento DOM para obtener el componente React de respaldo?
Esta pregunta se ha planteado anteriormente en el contexto de su uso en el código de producción. Sin embargo, mi atención se centra en las compilaciones de desarrollo con el fin de depurar.
Estoy familiarizado con la extensión de depuración de Chrome para React , sin embargo, esto no está disponible en todos los navegadores. Al combinar el explorador DOM y la consola, es fácil usar el acceso directo '$0' para acceder a la información sobre el elemento DOM resaltado.
Me gustaría escribir un código como este en la consola de depuración: getComponentFromElement($0).props
Incluso en una compilación de desarrollo de React, ¿no hay ningún mecanismo para usar tal vez el ReactId del elemento para llegar al componente?
Aquí está el ayudante que uso: (actualizado para trabajar con React <16 y 16+)
function FindReact(dom, traverseUp = 0) { const key = Object.keys(dom).find(key=>{ return key.startsWith("__reactFiber$") // react 17+ || key.startsWith("__reactInternalInstance$"); // react <17 }); const domFiber = dom[key]; if (domFiber == null) return null; // react <16 if (domFiber._currentElement) { let compFiber = domFiber._currentElement._owner; for (let i = 0; i < traverseUp; i++) { compFiber = compFiber._currentElement._owner; } return compFiber._instance; } // react 16+ const GetCompFiber = fiber=>{ //return fiber._debugOwner; // this also works, but is __DEV__ only let parentFiber = fiber.return; while (typeof parentFiber.type == "string") { parentFiber = parentFiber.return; } return parentFiber; }; let compFiber = GetCompFiber(domFiber); for (let i = 0; i < traverseUp; i++) { compFiber = GetCompFiber(compFiber); } return compFiber.stateNode; }Uso:
const someElement = document.getElementById("someElement"); const myComp = FindReact(someElement); myComp.setState({test1: test2});Nota: Esta versión es más larga que las otras respuestas, porque contiene código para atravesar desde el componente que envuelve directamente el nodo dom. (sin este código, la función FindReact fallaría en algunos casos comunes, como se ve a continuación)
Digamos que el componente que desea encontrar ( MyComp ) se ve así:
class MyComp extends Component { render() { return ( <InBetweenComp> <div id="target">Element actually rendered to dom-tree.</div> </InBetweenComp> ); } } En este caso, llamar a FindReact(target) devolverá (de manera predeterminada) la instancia de InBetweenComp , ya que es el primer componente antecesor del elemento dom.
Para resolver esto, aumente el argumento traverseUp hasta que encuentre el componente que desea:
const target = document.getElementById("target"); const myComp = FindReact(target, 1); // provide traverse-up distance herePara obtener más detalles sobre cómo atravesar el árbol de componentes de React, consulte aquí .
Los componentes de función no tienen "instancias" de la misma manera que las clases, por lo que no puede simplemente modificar la función FindReact para devolver un objeto con forceUpdate , setState , etc. para los componentes de función.
Dicho esto, al menos puede obtener el nodo React-fiber para esa ruta, que contiene sus accesorios, estado y demás. Para hacerlo, modifique la última línea de la función FindReact para simplemente: return compFiber;
Aquí tienes. Esto es compatible con React 16+
window.findReactComponent = function(el) { for (const key in el) { if (key.startsWith('__reactInternalInstance$')) { const fiberNode = el[key]; return fiberNode && fiberNode.return && fiberNode.return.stateNode; } } return null; };Acabo de leer los documentos y, afaik, ninguna de las API expuestas externamente le permitirá ingresar directamente y encontrar un componente React por ID. Sin embargo, puede actualizar su llamada React.render() inicial y mantener el valor de retorno en algún lugar, por ejemplo:
window.searchRoot = React.render(React.createElement...... Luego puede hacer referencia a searchRoot y mirarlo directamente, o atravesarlo usando React.addons.TestUtils . por ejemplo, esto le dará todos los componentes:
var componentsArray = React.addons.TestUtils.findAllInRenderedTree(window.searchRoot, function() { return true; });Hay varios métodos incorporados para filtrar este árbol, o puede escribir su propia función para devolver solo los componentes en función de algún cheque que escriba.
Más sobre TestUtils aquí: https://facebook.github.io/react/docs/test-utils.html