typescript - Rendera Olika Komponent om Alla Komponenter returnerar Null i ReactJS


Jag har en föräldrakomponent som renderar 4 barn. Om alla 4 barnkomponenter returnerar null vill jag rendera en annan komponent.

Vad jag skulle vilja göra:

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>
  )
}

Svar #1

Om det antas att beslutet om huruvida null ska renderas eller inte fattas här i Parent-komponenten, kan du göra något liknande följande:

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

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

REDIGERA: Om föräldrakomponenten alltid returnerar element, och det är upp till barnkomponenten att avgöra om den ska returnera null eller inte, då är dina alternativ mycket begränsade. Barnet kommer inte att renderas förrän i framtiden (det är precis efter att föräldern avslutar rendering, men det är fortfarande i framtiden), så de element som föräldern har skapat har ingen information om vad som slutligen kommer att renderas.

Det bästa jag kan komma på är att ha någon statisk hjälpfunktion som kallas som en del av barnets logik, och som du kan kalla i föräldern för att få en förhandsvisning av vad barnet kan göra. Till exempel:

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;
  }
}

Används i föräldern något sådant här:

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

Svar #2

En intressant lösning men detta skulle fungera:

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;

I huvudsak är allNull en tillståndsvariabel som är en boolean, den antar att alla barnelement är null tills motsatsen bevisas. När det är fallet ändras den till false, och då kommer barnen att visas.

När jag säger om null är det bara logiken för att tala om om det är null, när du förstår det bör det fungera (detta är inte heller TypeScript)