有没有办法判断 ReactElement 是否呈现 "null"?
Is there a way to tell if ReactElement renders "null"?
在我的 JSX 中,我有一个条件渲染逻辑的情况 - 当元素 A 渲染某些东西(它是 render()
函数 returns 除了 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()
检查吗?
不,无法确定 child 使用 React 将呈现什么。执行此操作的标准方法是公开一些实用函数,说明 A 是否将呈现。
类似于:
if (AUtils.isStoryValid(story)) {
return <A story={story} />;
} else {
return <B story={story} />;
}
你可以使用下面的高阶组件(HOC)来拦截ElementA的render方法,完成你想要的:
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}
/>
);
}
所以我 运行 陷入了不得不这样做的境地,这是一种可行的方法(尽管骇人听闻可能会让您哭泣)。
只应作为最后的手段使用,因为它确实是一个彻头彻尾的黑客攻击,根据组件的复杂性,您将遭受大约 0-20 毫秒的性能损失。
(假设您正在使用 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>
)
}
请注意,如果您的 ReactElement 已被编写为功能组件,您可以像调用任何其他函数一样调用该函数并检查其响应。
作为一个简单的例子,我有一个函数组件,它 returns 基于传入的道具的不同图标:
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
恰好是对象数组的属性,但我希望你能理解。
如果你的ElementA
是函数组件就容易了。在这种情况下,您可以像这样执行 smt:
function render() {
let ElemA = ElementA({ someProp: this.someVar});
if (ElemA === null) {
return (
<div>
{ ...someElements }
</div>
);
}
return (
<div>
{ ...someElements }
<ElementB />
<ElemA />
</div>
);
}
在我的 JSX 中,我有一个条件渲染逻辑的情况 - 当元素 A 渲染某些东西(它是 render()
函数 returns 除了 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()
检查吗?
不,无法确定 child 使用 React 将呈现什么。执行此操作的标准方法是公开一些实用函数,说明 A 是否将呈现。
类似于:
if (AUtils.isStoryValid(story)) {
return <A story={story} />;
} else {
return <B story={story} />;
}
你可以使用下面的高阶组件(HOC)来拦截ElementA的render方法,完成你想要的:
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}
/>
);
}
所以我 运行 陷入了不得不这样做的境地,这是一种可行的方法(尽管骇人听闻可能会让您哭泣)。
只应作为最后的手段使用,因为它确实是一个彻头彻尾的黑客攻击,根据组件的复杂性,您将遭受大约 0-20 毫秒的性能损失。 (假设您正在使用 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>
)
}
请注意,如果您的 ReactElement 已被编写为功能组件,您可以像调用任何其他函数一样调用该函数并检查其响应。 作为一个简单的例子,我有一个函数组件,它 returns 基于传入的道具的不同图标:
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
恰好是对象数组的属性,但我希望你能理解。
如果你的ElementA
是函数组件就容易了。在这种情况下,您可以像这样执行 smt:
function render() {
let ElemA = ElementA({ someProp: this.someVar});
if (ElemA === null) {
return (
<div>
{ ...someElements }
</div>
);
}
return (
<div>
{ ...someElements }
<ElementB />
<ElemA />
</div>
);
}