3

I'm trying to convert this functional component to class based component. I have tried for several hours but could not find where to place these const variables in component. If someone could write it out in class based component it will highly appreciated.

const useStyles = makeStyles(theme => ({
  typography: {
    padding: theme.spacing(2),
  },
}));
function SimplePopper() {
  const classes = useStyles();
  const [anchorEl, setAnchorEl] = React.useState(null);

  function handleClick(event) {
    setAnchorEl(anchorEl ? null : event.currentTarget);
  }

  const open = Boolean(anchorEl);
  const id = open ? 'simple-popper' : null;

  return (
    <div>
      <Button aria-describedby={id} variant="contained" onClick={handleClick}>
        Toggle Popper
      </Button>
      <Popper id={id} open={open} anchorEl={anchorEl} transition>
        {({ TransitionProps }) => (
          <Fade {...TransitionProps} timeout={350}>
            <Paper>
              <Typography className={classes.typography}>The content of the Popper.</Typography>
            </Paper>
          </Fade>
        )}
      </Popper>
    </div>
  );
}

export default SimplePopper;
Mavi Domates
  • 4,262
  • 2
  • 26
  • 45
Basir Baig
  • 111
  • 1
  • 8
  • 1
    It is not that difficult to convert a `functional component` to `class based`. If you have enough understanding of `ES6` it is pretty easy. Whatever `JSX` you return in the function, Just place it in the `render` method of the class. – James Jun 04 '19 at 10:52
  • @james problem is I dont know where to put these variables "id" and "open" and function "SimplePooper" and "handleClick" as mentioned in code in class based component. – Basir Baig Jun 04 '19 at 10:57
  • Check my answer for your above comment. – James Jun 04 '19 at 11:58

2 Answers2

4
    import React, { Component } from "react";
    import { createMuiTheme } from "@material-ui/core/styles";
    import Typography from "@material-ui/core/Typography";
    import Button from "@material-ui/core/Button";
    import Fade from "@material-ui/core/Fade";
    import Paper from "@material-ui/core/Paper";
    import Popper from "@material-ui/core/Popper";
    import { withStyles } from "@material-ui/styles";

    const theme = createMuiTheme({
      spacing: 4
    });

    const styles = {
      typography: {
        padding: theme.spacing(2)
      }
    };
    class SimplePopper extends Component {
      constructor(props) {
        super(props);
        this.state = { anchorEl: null, open: false };
      }
      flipOpen = () => this.setState({ ...this.state, open: !this.state.open });
      handleClick = event => {
        this.state.ancherEl
          ? this.setState({ anchorEl: null })
          : this.setState({ anchorEl: event.currentTarget });
        this.flipOpen();
      };

      render() {
        const open = this.state.anchorEl === null ? false : true;
        console.log(this.state.anchorEl);
        console.log(this.state.open);
        const id = this.state.open ? "simple-popper" : null;
        const { classes } = this.props;
        return (
          <div>
            <Button
              aria-describedby={id}
              variant="contained"
              onClick={event => this.handleClick(event)}
            >
              Toggle Popper
            </Button>
            <Popper
              id={id}
              open={this.state.open}
              anchorEl={this.state.anchorEl}
              transition
            >
              {({ TransitionProps }) => (
                <Fade {...TransitionProps} timeout={350}>
                  <Paper>
                    <Typography className={classes.typography}>
                      The content of the Popper.
                    </Typography>
                  </Paper>
                </Fade>
              )}
            </Popper>
          </div>
        );
      }
    }

    export default withStyles(styles)(SimplePopper);
Brad Ball
  • 599
  • 3
  • 5
  • thankyou for your effort.But it is opened when button is clicked but does not close on when button i clicked again.Can you fix this bug please.Thanks – Basir Baig Jun 04 '19 at 11:27
  • @BasirBaig Here is a fix to that sir! If this solves your solution please check my answer as the answer so I get points. Thank you! – Brad Ball Jun 04 '19 at 14:18
1

First thing one need to understand is, how class based and functional components work. Also, when and where you use it.

In short, I can say functional components are Used for presenting static data. And class based are Used for dynamic source of data.

Here are few links for your reference.

Class based component vs Functional components what is the difference ( Reactjs ) and React functional components vs classical components

To answer your specific question.

import React, { Component } from 'react';
import { withStyles, makeStyles } from '@material-ui/styles';

const useStyles = makeStyles(theme => ({
      typography: {
        padding: theme.spacing(2),
      },
}));

class SimplePopper extends Component {
   constructor(props){
      super(props)
      this.state = { anchorEl: null, setAnchorEl: null }; <--- Here see the state creation
      this.handleClick= this.handleClick.bind(this);
    }

   handleClick(event) {
        const { anchorEl, setAnchorEl } = this.state; <--- Here accessing the state
        setAnchorEl(anchorEl ? null : event.currentTarget);
   }

   render() {
      const { anchorEl, setAnchorEl } = this.state; <--- Here accessing the state
      const open = Boolean(anchorEl);
      const id = open ? 'simple-popper' : null;
      const { classes } = this.props;

      return (
        <div>
           ............Rest of the JSX............
        </div>
      );
    }
 }
export default withStyles(useStyles)(SimplePopper);

Note that here I've used withStyles to wrap the style to your component. So, that the styles will be available as classNames.

Explore the difference and convert the rest

This is more enough to begin with.

James
  • 2,874
  • 4
  • 30
  • 55