在我的JSX中,我有一个条件渲染逻辑的情况 - 当元素A渲染某些东西时(它的render()
函数返回除null
之外的其他东西),然后渲染元素B ,就在元素A的上方。
代码示例(简化)如下所示:
function render() {
let elemA = (<ElementA someProp={this.someVar} />);
if (elemA.isNull()) {
return (
<div>
{ ...someElements }
</div>
);
}
return (
<div>
{ ...someElements }
<ElementB />
{ elemA }
</div>
);
}
所以我的问题是 - 有没有办法进行elemA.isNull()
检查?
答案 0 :(得分:8)
不,没有办法确定孩子使用React渲染的内容。执行此操作的标准方法是公开一些实用程序函数,该函数指示A是否将呈现。
类似的东西:
if (AUtils.isStoryValid(story)) {
return <A story={story} />;
} else {
return <B story={story} />;
}
答案 1 :(得分:3)
您可以使用以下高阶组件(HOC)拦截ElementA的渲染方法并完成您想要的任务:
function withNullCheck(WrappedComponent) {
return class NullChecker extends WrappedComponent {
render() {
const result = super.render();
return(
<div>
{ this.props.alwaysPrefix }
{ result && this.props.ifNotNullPrefix }
{ result ? result : this.props.ifNull }
{ result && this.props.ifNotNullAppend }
{ this.props.alwaysAppend }
</div>
);
}
}
}
您可以这样使用它:
const NullCheckedElementA = withNullCheck(ElementA);
...
function render() {
return (
<NullCheckedElementA
alwaysPrefix={someElements}
ifNotNullPrefix={elemB}
someProp={this.someVar}
/>
);
}
答案 2 :(得分:2)
如果您的ElementA
是函数组件,这将很容易。在这种情况下,您可以这样做:
function render() {
let ElemA = ElementA({ someProp: this.someVar});
if (ElemA === null) {
return (
<div>
{ ...someElements }
</div>
);
}
return (
<div>
{ ...someElements }
<ElementB />
<ElemA />
</div>
);
}
答案 3 :(得分:1)
请注意,如果您的ReactElement已被编写为功能组件,则可以像调用其他任何函数一样调用该函数并检查其响应。 作为一个简单的示例,我有一个函数组件,该函数根据传入的道具返回不同的图标:
import React from "react";
import PersonIcon from "@material-ui/icons/Person";
import GroupIcon from "@material-ui/icons/People";
export default function EntityIcon({ entity }) {
switch (entity) {
case "people":
return <PersonIcon />;
case "groups":
return <GroupIcon />;
default:
console.error(`entity: ${entity} doesn't have an associated icon`);
return null;
}
}
上面通常引用为:
<ListItemIcon>
<EntityIcon entity={search.entity} />
</ListItemIcon>
但是如果需要,我可以做一些条件魔术:
if (EntityIcon({ entity: item.entity })) {
... conditional magic
}
在我的用例中, search.entity
和item.entity
恰好是对象数组的属性,但是希望您能理解。
答案 4 :(得分:0)
所以我遇到了一个我不得不这样做的情况,这是一种有效的方法(尽管黑客可能会让你哭泣)。
只应该作为最后的手段使用,因为它确实是一个完全黑客攻击,并且你会根据组件的复杂性采取约0-20ms的性能。 (提供商在那里假设你正在使用redux,你的组件取决于你的redux状态):
import { renderToStaticMarkup } from 'react-dom/server';
import { Provider } from 'react-redux';
import store from 'pathToYourReduxStoreInstance';
export default function isRenderingNull(componentInstance) {
return !renderToStaticMarkup(
<Provider store={store}>
{componentInstance}
</Provider>
)
}