javascriptreactjssnackbaralerts

React JS: Passing function as props is not working as expected


I'm fairly new to React JS and I have a question. I've been trying to search the internet about my problem but I cannot find a solution. Here it goes: I have 2 files, Header.tsx and Alerts.tsx. In Header.tsx there is a function named alertData that indicates the severity of an alert.

const Header = () => {

   useEffect(() => {
   setSomething(getSomething(alertData));
   }, []);

   const alertData = (data: any) => {
   const type: SOMETHING_TYPE = data.type
   switch (type) {
     case 'HEALTH': {
       const message = {
          type: 'info',
          message: `Healthy:`
       }
       return message;
     }
     case 'WARNING': {
    const alert: Alert = data;
      const message = {
          type: 'error',
          message: `Warning: ${alert.severity}`
       }
       return message;
     }
   }

   return (
     <header>
        <Alerts data = {alertData}>
     </header>
   )

}

Here is the Alerts.tsx:

const Alerts = (data) => {

console.log("Data:", data)
const classes = useStyles();
const [open, setOpen] = useState(true);


const handleClose = (event, reason) => {
  if (reason === 'clickaway') {
    return;
  }

setOpen(false);
};

return (
  <div className={classes.root}>
    <Snackbar open={open} autoHideDuration={6000} onClose={handleClose} anchorOrigin={{ 
        vertical: 'top', horizontal: 'right' }}>
      <Alert onClose={handleClose} severity={type}>
         { message }
      </Alert>
  </Snackbar>
</div>
);
}

I have put alertData as a props for <Alert/> in Header.tsx but alert is still not showing in the UI. I've checked in console.log and this is the data that is being passed: enter image description here

I was expecting message to be passed to Alerts so that it can be displayed in the UI but its not showing. What am I doing wrong?


Solution

  • The reason why you passed a function instead of a message variable, is because in your Header.tsx you did not evaluate the alertData function.

    const Header = () => {
      // ...
    
      return (
        <header>
          <Alerts data={alertData}>
        </header>
      );
    }
    

    it should be changed to:

    const Header = () => {
      const [someData, setSomeData] = useState();
    
      return (
        <header>
          <Alerts data={alertData(someData)}>
        </header>
      );
    }
    

    And yet, in your Alerts.tsx, the variable data is actually an object that wrapping the field data instead of the data you want. therefore, you should rewrite the component Alerts from:

    const Alerts = (data) => {
    }
    

    To

    // first approach: es6 destructing assignment
    const Alerts = ({data}) => {
      // ...
    }
    
    // second approach: create a new variable
    const Alerts = (props) => {
      const data = props.data;
      // ...
    }