简体   繁体   中英

Conditionally rendering content in react

I am having a functional component that takes two items as props. The values of each properties could be undefined , "" , null , "null" , or a valid string (for example, "test" ).

I need to conditionally render these props based on values

if prop1 and prop2 are both present then it should display as prop1(prop2) , if either one of them are present then it should either be prop1 or just prop2 . In case both of them are not present then should display "Not Available". Only valid strings should be taken. If values has either undefined , "" , null , "null" it should not be displayed.

I am having trouble building up the logic. This is what I have tried.

const Test = (props) => {
   let { prop1, prop2 } = props;
    let content: string;
    if ((!prop1 || prop1 === "null") && (!prop2 || prop2 === "null")) {
        content = "Not Available";
    } else if (!!prop1 && !!prop2) {
        content = `${prop1} (${prop2})`;
    } else {
       content = `${prop1 || prop2}`;
    }
   
  return (
    <>
      {content}
    </>
  );

}

This maybe one way to achieve the desired objective:

const isPropInvalid = inp => [undefined, null, '', ' '].includes(inp);

const content = isPropInvalid(prop1)
  ? isPropInvalid(prop2) ? 'Not Available' : prop2
  : isPropInvalid(prop2) ? prop1 : `${prop1} (${prop2})`

Explanation

  • set-up an array with elements that are considered 'invalid' (ie, undefined, null, '', 'null')
  • use simple if-else or ?: ternary-operators to assign the appropriate value to content based on whether one or both props are invalid.

Code Snippet

 const isPropInvalid = inp => [undefined, null, '', 'null'].includes(inp); const content = (prop1, prop2) => isPropInvalid(prop1)? isPropInvalid(prop2)? 'Not Available': prop2: isPropInvalid(prop2)? prop1: `${prop1} (${prop2})`; console.log(content('abc', 'xyz')); console.log(content()); console.log(content(null, 'xyz')); console.log(content('abc', 'null'));

How about a separate function that returns whether or not the value is valid?

function propIsValid(value) {
  // valid if truthy and not "null" (string)
  return !!prop && value != "null";
}

The above checks for a thuthy value, which means that all falsy values are considered invalid. This includes null , undefined and "" , but also false , NaN and 0 . Which might or might not be a problem, depending on your context.

If you want a more target approach you could use the following:

const invalid = [undefined, null, "", "null"];
return !invalid.includes(value);

Then simplify your component to:

const Test = ({ prop1, prop2 }) => {
  const allValid   = [prop1, prop2].every(propIsValid);
  const firstValid = [prop1, prop2].find(propIsValid);

  if (allValid) {
    return <>{prop1}({prop2})</>;
  } else if (firstValid) {
    return <>{firstValid}</>;
  } else {
    return <>Not Available</>;
  }
}

This uses every() to check if both are valid, but this could also be written as propIsValid(prop1) && propIsValid(prop2) . find() is used to find the first valid value (if any), this does assume that a valid value is always thuthy .

I guess this is a tricky condition by itself, so I wouldn't worry too much if it looks a bit weird. One think you can do tho is to organize the component code in variables and smaller functions like so:

const isDefined = (value) => value !== "null" && !!value
const buildString = (prop1, prop2) => {
  let string = prop1 || prop2
  return prop1 && prop2
    ? `${string} (${prop2})`
    : string
}

const Test = ({ prop1, prop2 }) => {
  const someDefined = isDefined(prop1) || isDefined(prop2);
   
  return (
    <>
      {!someAreDefined && "Not Available"}
      {someAreDefined && buildString(prop1, prop2)}
    </>
  );
}

I think that helps a lot with readability and understanding the flow and possible outputs for this component.

Just use a ternary

(prop1 && !/null/.test(prop1)) && (prop2 && !/null/.test(prop2)) ? `${prop1}(${prop2})` : prop1 && !/null/.test(prop1) ? `${prop1}` : prop2 && !/null/.test(prop2) ? `${prop2}` : 'Not Available';

Since undefined "" and null are falsey in nature it will only use regex to test for the pattern null if it needs to. If there are any other values that you want to be considered invalid, just add them to the regex.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM