web-dev-qa-db-ja.com

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()をチェックする方法はありますか?

16
mdziekon

いいえ、Reactを使用して子供が何をレンダリングするかを決定する方法はありません。これを行う標準的な方法は、Aがレンダリングするかどうかを示すユーティリティ関数を公開することです。

何かのようなもの:

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

次の高次コンポーネント(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} 
      />
    );

}
5
Pablo

ElementAが関数コンポーネントであれば簡単です。この場合、次のようにsmtを実行できます。

    function render() {
    let ElemA = ElementA({ someProp:  this.someVar});

    if (ElemA === null) {
        return (
            <div>
                { ...someElements }
            </div>
        );
    }

    return (
        <div>
            { ...someElements }
            <ElementB />
            <ElemA />
        </div>
    );
}
0
Eugene

だから私はこれをしなければならないという状況に遭遇しました、これがうまくいく方法です(ハッキングはあなたを泣かせるかもしれませんが)。

これは実際には完全なハックであり、コンポーネントの複雑さに応じてパフォーマンスに最大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>
  )
}
0
SirRodge

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私のユースケースでは、たまたまオブジェクトの配列のプロパティですが、あなたがその考えを理解してくれることを願っています。

0
Shiraz