TechGeek
TechGeek

Reputation: 508

How to use array objects based on condition using React JS

I'm using react functional components inside that, I have two different array objects. I would like to render the array objects based on the condition which I have. I'm using the function hooks to define a reference and assign to it dynamically. But, this is returning null. can someone help me on this ? In the below code isDemandGraph is returning null while rendering.

     function gridHeatMap(props) {
          const heatMap = [
            { color: 'redVeryHigh', value: 50 },
            { color: 'redHigh', value: 25 },
            { color: 'redMedium', value: 20 },
            { color: 'redLow', value: 15 },
            { color: 'white', value: 0 },
            { color: 'greenLow', value: 15 },
            { color: 'greenMedium', value: 20 },
            { color: 'greenHigh', value: 25 },
            { color: 'greenVeryHigh', value: 50 },
          ];
        
          const demandHeatMap = heatMap.reverse();
        
          const isDemandGraph = useRef(null);
        
          const { height, title, viewName } = props;
          const classes = useStyles();
        
          return (
            <div className={classes.root}>
              <div className={classes.title}>{title}</div>
              <Grid container spacing={0}>
                {viewName === 'demand' ? { isDemandGraph: heatMap } : { isDemandGraph: demandHeatMap }}
                {isDemandGraph.map((item, index) => {
                  return (
                    <Grid item style={{ flexGrow: '1', height, width: '11%' }} className={item.color}>
                    </Grid>
               </Grid>
            </div>
)

Upvotes: 0

Views: 2340

Answers (3)

secan
secan

Reputation: 2679

I think this is how I would go (please notice I modified a bit the returned JSX, as the one in your code did not look correct to me, so you might want to double check it):

import React, { useState, useMemo, useEffect } from 'react';
// ... other imports

function gridHeatMap({ height, title, viewName }) {
  const heatMap = useMemo(() => ([
    { color: 'redVeryHigh', value: 50 },
    { color: 'redHigh', value: 25 },
    { color: 'redMedium', value: 20 },
    { color: 'redLow', value: 15 },
    { color: 'white', value: 0 },
    { color: 'greenLow', value: 15 },
    { color: 'greenMedium', value: 20 },
    { color: 'greenHigh', value: 25 },
    { color: 'greenVeryHigh', value: 50 },
  ]), []);
  
  const [currentHeatMap, setCurrentHeatMap] = useState(heatMap);
  
  useEffect(() => {
    viewName === 'demand'
      ? setCurrentHeatMap(heatMap)
      : setCurrentHeatMap(heatMap.reverse());
  }, [viewName]);
  
  const classes = useStyles();
  
  return (
    <div className={classes.root}>
      <div className={classes.title}>{title}</div>
      
      <GridContainer spacing={0}>
        {
          currentHeatMap.map((item, index) => (
            <Grid
              key={`grid-${index}-${item.color}`}
              className={item.color}
              style={{ flexGrow: '1', height, width: '11%' }}
              item
            />
          ));
        }
      </GridContainer>
    </div>
  );
}

export default gridHeatMap;

Upvotes: 1

dhruv479
dhruv479

Reputation: 321

It won't work that way, calling the isDemandGraph inside the ternary operator does not assign value to the same. Also, you should use useState instead of useRef for your usecase. I am adding the updated code snippet, it should work as expected:

 function gridHeatMap(props) {
          const heatMap = [
            { color: 'redVeryHigh', value: 50 },
            { color: 'redHigh', value: 25 },
            { color: 'redMedium', value: 20 },
            { color: 'redLow', value: 15 },
            { color: 'white', value: 0 },
            { color: 'greenLow', value: 15 },
            { color: 'greenMedium', value: 20 },
            { color: 'greenHigh', value: 25 },
            { color: 'greenVeryHigh', value: 50 },
          ];
        
          const demandHeatMap = heatMap.reverse();
        
          const { height, title, viewName } = props;
          const [isDemandGraph, setIsDemandGraph ] = useState(viewName === 'demand' ? heatMap : demandHeatMap);
          // setIsDemandGraph can be used to update the value of `isDemandGraph`
          
          const classes = useStyles();
        
          return (
            <div className={classes.root}>
              <div className={classes.title}>{title}</div>
              <Grid container spacing={0}>
                {isDemandGraph.map((item, index) => {
                  return (
                    <Grid item style={{ flexGrow: '1', height, width: '11%' }} className={item.color}>
                    </Grid>
            </div>

Upvotes: 1

Giovanni Esposito
Giovanni Esposito

Reputation: 11156

I suggest you to use useState instead of useRef and use useEffect to listen prop changes like:

function gridHeatMap(props) {
          const { height, title, viewName } = props;
          const [isDemandGraph, setisDemandGraph] = useState([]);
          const classes = useStyles();

          const heatMap = [
            { color: 'redVeryHigh', value: 50 },
            { color: 'redHigh', value: 25 },
            { color: 'redMedium', value: 20 },
            { color: 'redLow', value: 15 },
            { color: 'white', value: 0 },
            { color: 'greenLow', value: 15 },
            { color: 'greenMedium', value: 20 },
            { color: 'greenHigh', value: 25 },
            { color: 'greenVeryHigh', value: 50 },
          ];
        
          const demandHeatMap = heatMap.reverse();
        
          useEffect(() => {
             viewName === 'demand' ?  setisDemandGraph(heatMap) : setisDemandGraph(demandHeatMap);
          }, [viewName]);
        
          return (
            <div className={classes.root}>
              <div className={classes.title}>{title}</div>
              <Grid container spacing={0}>
                {isDemandGraph.map((item, index) => {
                  return (
                    <Grid item style={{ flexGrow: '1', height, width: '11%' }} className={item.color}>
                    </Grid>
            </div>
)

Upvotes: 1

Related Questions