ReactDOM.findDOMNode () с использованием дочернего элемента React.Children - PullRequest
0 голосов
/ 08 февраля 2020

Я пытаюсь получить доступ к указанному c дочернему узлу DOM компонента следующим образом:

let targetChild = null;
React.Children.forEach(children, child => {
    if (child.type.displayName === 'TargetElement') {
        targetChild = child;
    }
});

const targetEl = ReactDOM.findDOMNode(targetChild);

Однако я получаю сообщение об ошибке:

Uncaught Error: Аргумент, кажется, не является ReactComponent.

Когда я выхожу из системы typeof targetChild, я получаю object. Кто-нибудь знает, как это исправить? Спасибо!

Ответы [ 2 ]

1 голос
/ 10 февраля 2020

Прежде всего findDOMNode не следует использовать

Также обратите внимание, что typeof null равно object

Проблема в том, что вы передаете React Element вместо React Component's instance

Подробнее о разнице между React Element против React Component против React Component instance https://reactjs.org/blog/2015/12/18/react-components-elements-and-instances.html* 1024 Если коротко *

, если UL - это React Component (компонент класса или компонент функции), тогда <UL /> - это React element

Также обратите внимание, что вы можете использовать только findDOMNode Class Component не компонент функции

Документация выглядит немного вводящей в заблуждение, поскольку в ней написано

ReactDOM.findDOMNode (component)

обратите внимание, что написано Component, но я провел некоторый поиск и обнаружил, что вам нужно передать component's instance вместо компонента

, например, следующее будет работать, потому что this будет указывать на экземпляр компонента

import React  from "react";
import ReactDOM from "react-dom";

const UL = props => {
  return <ul>{props.children}</ul>;
};

class List extends React.Component {
  componentDidMount() {
    console.log('printing', ReactDOM.findDOMNode(this));
  }
  render() {
    return <li>this is targe element</li>;
  }
}

export default function App() {
  return (
    <div className="App">
      <UL>
        <li>Hello CodeSandbox</li>
        <List />
        <li>Start editing to see some magic happen!</li>
      </UL>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

, но следующее не будет работать, потому что мы передаем React element вместо экземпляра компонента

import React from "react";
import ReactDOM from "react-dom";

class UL extends React.Component {
  componentDidMount() {
    let element = null;
    React.Children.forEach(this.props.children, (child, index) => {
      if (index === 1) {
        console.log('logging child', child);
        element = child;
      }
    });
    console.log('printing', ReactDOM.findDOMNode(element));
  }
  render() {
    return <ul>{this.props.children}</ul>;
  }
};

class List extends React.Component {
  render() {
    return <li>this is targe element</li>;
  }
}

List.displayName = 'TargetElement';

export default function App() {
  return (
    <div className="App">
      <UL>
        <li>Hello CodeSandbox</li>
        <List />
        <li>Start editing to see some magic happen!</li>
      </UL>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

0 голосов
/ 15 февраля 2020

Чтобы получить элемент DOM конкретного экземпляра компонента React, вам нужно использовать ссылки обратного вызова .

Вот демонстрация для вас:

const children = ['Bob', 'Jeff', 'Kate'];
const TARGET_NODE = 'Jeff';
let jeffRef;

const setRef = (el, label) => {
	if(label === TARGET_NODE) {
		jeffRef = el;
	}
}

const SampleApp = ({children}) => (
	<ul>
  	{children.map((child, index) => (
	    	<li key={index} ref={el => setRef(el, child)}>{child}</li>
	))}
	</ul>
)

ReactDOM.render(<SampleApp children={children}/>, document.querySelector("#app"))

console.log(jeffRef)	//	Should output: <li>Jeff</li>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="app"></div>

PS: По моему мнению, в большинстве случаев доступ к элементам DOM можно избежать. Возможно, вы захотите пересмотреть это. Вместо этого вы можете контролировать / обновлять элемент, используя состояние компонента.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...