Home > other >  Render Different Component if All Components return Null in ReactJS
Render Different Component if All Components return Null in ReactJS

Time:01-05

I have a parent component that renders 4 children. If all 4 child components return null, I want to render a different component.

What I would like to do:

const Child = () => {

  return(<div> hi </div>);   // I expect if I return(null) to render Nothing Found whic doesn't happen
}
const Parent = () => {
  const children = [1, 2, 3].map(() => {
    return (<Child />);
  });

    return (
    <div>
      {children.some(element => element !== null) ? (
          children
        ) : (
          <div>Nothing found</div>
      )}
    </div>
  )
}

CodePudding user response:

Assuming the decision of whether to render null or not is being made here in the Parent component, you can do something like the following:

function Parent() {
  const children = [1, 2, 3].map(() => {
    return null, or whatever;
  });

  return (
    <>
      {children.some(element => element !== null) ? (
        children
      ) : (
        <div>Nothing found</div>
      )}
    </>
  );
}

EDIT: If the parent component is always returning elements, and it's up to the child component to decide whether to return null or not, then your options are very limited. The child won't render until the future (it's right after the parent finishes rendering, but that's still in the future), so the elements that the parent has created don't have any information about what will eventually be rendered.

The best i can think of is to have some static utility function which gets called as part of the child's logic, and which you can call in the parent to get a preview of what the child might do. For example:

export const willRender = (props) => {
  if (/* check something on the props */) {
    return false;
  } else {
    return true;
  }
}

export const Child = (props) => {
  if (willRender(props)) {
    return <div>Hello World</div>
  } else {
    return null;
  }
}

Used in the parent something like this:

function Parent() {
  return (
    <>
      {[1, 2, 3].some(() => willRender({ /* whatever props */ })) ? (
         [1, 2, 3].map(() => <Child /* same props */ />)
       ) : (
         <div>Nothing found</div>
       )}
    </>
  );
}

CodePudding user response:

An intersting solution but this would work:

import React, { useState } from 'react';

const Child = (props) => {
    if (null) return false;
    else {
        props.setAllNull(false);
        return <div>hi</div>;
    }
};
const Parent = () => {
    const [allNull, setAllNull] = useState(true);
    const children = [1, 2, 3].map(() => {
        return <Child setAllNull={setAllNull} />;
    });

    return <div>{allNull ? <div>Nothing found</div> : children}</div>;
};

export default Parent;

Essentially the allNull is a state variable thats a boolean, it assumes all of the child components are null until proven otherwise. Once it is its changed to false, and then children will be displayed.

When i say if null thats just the logic for telling if its null once u get that it should work (also this isn't typescript)

CodePudding user response:

I think your problem could be solved by getting the children type with calling type method on react element like this child.type(). It will return null if Child component returns null:

const Child = (props) => {
  return (<div> hi </div>);
}

const NullChild = (props) => {
  return null;
}

const Parent = ({children}) => {
    return (
    <div>
      {children.some(element => element.type(element.props) !== null) ? (
          children
        ) : (
          <div>Nothing found</div>
      )}
    </div>
  )
}

function App() {
  const children = [1, 2, 3].map((i) => <Child key={i}/>);
  const nullChildren = [1, 2, 3].map((i) => <NullChild key={i} />);

  return (<div>
    <Parent>{children}</Parent>
    <hr/>
    <Parent>{nullChildren}</Parent>
  </div>);
}

ReactDOM.render(<App/>, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

<div id="root"></div>

  •  Tags:  
  • Related