данные о том, какие компоненты оказываемых какие может быть найден копаться в React компонентов внутренностей экземпляра, но вы сказали, что вы хотите сделать узел DOM и выяснить, какие Реагировать компонент вынес его, и это немного Сильнее.
вам действительно нужно манипулировать DOM после ли Реагировать флеши это, или вы контент для изменения Реагировать элемент (который получает вернулся из JSX/React.createElement
вызова) перед тем рендеринга в DOM происходит? В любом случае, перехват render
самостоятельно позволяет вам проверять элемент и делать то, что вы хотите с ним. Поскольку дочерние составные компоненты не расширяются до реальных узлов DOM до тех пор, вы получите только те, которые вам нужны.
Вот пример декоратора, который добавит свойство к каждому отдельному элементу, вынесенному данному класс:
function recursiveAddProps(elem, extraProps) {
if (!elem) return;
if (typeof elem === "string") {
// strings get turned into spans
return React.createElement("span", extraProps, elem);
}
const props = elem.props || {};
const newChildren = React.Children.map(props.children, child =>
recursiveAddProps(child, extraProps)
)
return React.cloneElement(elem, extraProps, newChildren);
}
function DecoratorComponent(klass) {
const oldRender = klass.prototype.render;
klass.prototype.render = function() {
const elem = oldRender.apply(this, arguments);
const name = this.constructor.displayName || this.constructor.name;
return recursiveAddProps(elem, {
className: "myOverriddenClass" // this will set className on every element
});
};
return klass;
}
Используя этих компоненты
class Foo extends React.Component {
render() {
return (
<div>
<div>Hi!</div>
<SomeOtherComponent />
{['a', 'b', 'c'].map(letter => <div>{letter}</div>)}
</div>
);
}
}
Foo = DecoratorComponent(Foo);
class SomeOtherComponent extends React.Component {
render() {
return (
<ul>
<li>Some</li>
<li>Other</li>
<li>Component</li>
</ul>
);
}
}
результаты кода в DOM:
<div class="myOverriddenClass" data-reactid=".0">
<div class="myOverriddenClass" data-reactid=".0.$/=10">
<span class="myOverriddenClass" data-reactid=".0.$/=10.$/=10">Hi!</span>
</div>
<ul data-reactid=".0.$/=11">
<li data-reactid=".0.$/=11.0">Some</li>
<li data-reactid=".0.$/=11.1">Other</li>
<li data-reactid=".0.$/=11.2">Component</li>
</ul>
<div class="myOverriddenClass" data-reactid=".0.$/=12=20">
<span class="myOverriddenClass" data-reactid=".0.$/=12=20.$/=10">a</span>
</div>
<div class="myOverriddenClass" data-reactid=".0.$/=12=21">
<span class="myOverriddenClass" data-reactid=".0.$/=12=21.$/=10">b</span>
</div>
<div class="myOverriddenClass" data-reactid=".0.$/=12=22">
<span class="myOverriddenClass" data-reactid=".0.$/=12=22.$/=10">c</span>
</div>
</div>
Вы можете видеть, что класс был добавлен к каждому элементу за исключением тех, которые оказываются SomeOtherComponent
- ul
и li
s.
Если вы хотите установить какой-либо специальный атрибут на узлах DOM, чтобы вы могли определить, отобразили ли его компонент Foo
, вы можете указать атрибут data-
, а React будет сбрасывать его в DOM.
<div data-rendered-by="Foo" data-reactid=".0">
<div data-rendered-by="Foo" data-reactid=".0.$/=10">
<span data-rendered-by="Foo" data-reactid=".0.$/=10.$/=10">Hi!</span>
</div>
<ul data-reactid=".0.$/=11">
<li data-reactid=".0.$/=11.0">Some</li>
<li data-reactid=".0.$/=11.1">Other</li>
<li data-reactid=".0.$/=11.2">Component</li>
</ul>
<div data-rendered-by="Foo" data-reactid=".0.$/=12=20">
<span data-rendered-by="Foo" data-reactid=".0.$/=12=20.$/=10">a</span>
</div>
<div data-rendered-by="Foo" data-reactid=".0.$/=12=21">
<span data-rendered-by="Foo" data-reactid=".0.$/=12=21.$/=10">b</span>
</div>
<div data-rendered-by="Foo" data-reactid=".0.$/=12=22">
<span data-rendered-by="Foo" data-reactid=".0.$/=12=22.$/=10">c</span>
</div>
</div>
Здесь каждый узел DOM имеет атрибут data-rendered-by="Foo"
, что позволяет говорить с DOM в одиночку, что узел был оказываемая Foo
.
Here's a working example на JSBin: https://jsbin.com/tuliqu/edit?js,output
Это довольно мощная абстракция, которая может позволит вам делать то, что вы хотите, даже не прикасаясь к DOM; например, в React CSS Modules, DOM не затрагивается - the components are simply extended and render is overridden.
Я не верю, что то, что вы пытаетесь сделать, это то, что поддерживается реакцией. Между узлами, создаваемыми при сопоставлении над '['a', 'b', 'c']' и ' ', нет различий, кроме метаданных типа 'displayName'. Не могли бы вы объяснить большую проблему, которую вы пытаетесь решить, и, может быть, мы могли бы взломать ее решение так, чтобы реагировать более канонически? –
Могу ли я понять, что у вас разные компоненты, написанные в тех же частях DOM? Можете ли вы немного рассказать о том, почему это происходит? –