问题 有没有办法判断ReactElement是否呈现“null”?


在我的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() 检查?


11804
2017-10-14 22:04


起源

React可能不会“知道”此时elemA是否已呈现任何内容,因为render方法只描述了一个结构。 - David
好的,所以在这种情况下,我看到两个选项来解决这个问题: 一个) 在ElementA类中创建一个自定义方法,它会告诉我它是否会呈现 null 或者是其他东西 b) 在ElementA中移动条件渲染,并传递任何内容作为prop进行渲染。 |我不确定前一个选项是否真的可行,但...... - mdziekon
如果ElementA是纯组件(由props描述onky),那么也应该可以从this.someVar告诉ElementA是否会被渲染。 - wintvelt


答案:


不,没有办法确定孩子将使用React渲染什么。执行此操作的标准方法是公开一些实用程序函数,该函数指示A是否将呈现。

就像是:

if (AUtils.isStoryValid(story)) {
  return <A story={story} />;
} else {
  return <B story={story} />;
}

7
2017-08-21 01:13





您可以使用以下高阶组件(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} 
      />
    );

}

2
2017-09-07 17:41





所以我遇到了一个我不得不这样做的情况,这是一种有效的方式(虽然黑客可能会让你哭泣)。

应该只作为最后的手段使用,因为它确实是一个彻头彻尾的黑客攻击,你将需要大约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>
  )
}

0
2018-03-29 21:40