Home > Mobile >  How to wait until value is set to grab prop value
How to wait until value is set to grab prop value

Time:08-10

I am trying to figure out this issue where .toUpperCase() in one of my components is giving an error:

TypeError: Cannot read properties of undefined (reading 'toUpperCase')

I believe this is being caused because of a race condition in grabbing the prop in my reusable component called Icon as it happens about 50% of the time when I refresh the page.

import React from 'react';
import PropTypes from 'prop-types';
import './icons-svg-color.css';


const Icon = (props) => {
  const { icon, className } = props;

  return (
    <div className={`icon-32 ${className}`} style={{ backgroundImage: `url('data:image/svg xml;utf-8,<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32"><style>.text {font-family: sans-serif; font-size: 10px; fill:#FFF;}</style><circle  cx="16" cy="16" r="16" fill="#1d5baa"/><text x="50%" y="63%" text-anchor="middle" >${icon.toUpperCase()}</text></svg>')` }}>
      <div className={`icon-32  ${className}`} style={{ backgroundImage: `url(/static/images/assets/icons/svg/color/${icon}.svg)` }} />
    </div>
  );
};

Icon.defaultProps = {
  className: '',
};

Icon.propTypes = {
  icon: PropTypes.string.isRequired,
  className: PropTypes.string
};

export default Icon;

Here is where it is being used:

  const renderMenuItems = () => {
    return chartMarkets.map((type) => {
      return (
        <MenuItem value={type} onClick={event => handleSelection(event)}>
          <Icon className={classes.menuItemImage} icon={type} />
          <Typography variant="body1">{type}</Typography>
        </MenuItem>
      );
    });
  };

I have tried stuff like defaulting it to empty string, but that is not the outcome I want as the app no longer crashes but the icon is not there. I also have tried conditional rendering where I pass in the value into the prop after the value is defined like so:

<MenuItem value={type} onClick={event => handleSelection(event)}>
   <Icon className={classes.menuItemImage} ***icon={type && type}*** />
   <Typography variant="body1">{type}</Typography>
</MenuItem>

But still has the same issue where it crashes the program with that same error. Also have tried using useEffect in the reusable Icon component like so:

  useEffect(() => {
    
  }, [icon]);

Is there any other solutions that I can try? Thanks!

CodePudding user response:

You can do simple like

return (
    icon && (<div className={`icon-32 ${className}`} style={{ backgroundImage: `url('data:image/svg xml;utf-8,<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32"><style>.text {font-family: sans-serif; font-size: 10px; fill:#FFF;}</style><circle  cx="16" cy="16" r="16" fill="#1d5baa"/><text x="50%" y="63%" text-anchor="middle" >${icon.toUpperCase()}</text></svg>')` }}>
      <div className={`icon-32  ${className}`} style={{ backgroundImage: `url(/static/images/assets/icons/svg/color/${icon}.svg)` }} />
    </div>)
  );
  • Related