0

I am new to react and javascript. May I know how to call other class function from current class?

I only able to use prop to pass the data between class.

For example, I have one toolbar and one user class. When I click the toolbar delete button. I want to call delete function in my user class. How to achieve this?

So this is my toolbar. When I click delete button,I want to trigger deleteUser in my user class.

let EnhancedTableToolbar = props => {
const { numSelected, classes, selectedArray } = props;
  return (
    <Toolbar
      className={classNames(classes.root, {
        [classes.highlight]: numSelected > 0,
      })}
    >
      <div className={classes.title}>
        {numSelected > 0 ? (
          <Typography color="inherit" variant="subtitle1">
            {numSelected} selected
          </Typography>
        ) : (
          <Typography variant="h6" id="tableTitle">
            User List
          </Typography>
        )}
      </div>
      <div className={classes.spacer} />
      <div className={classes.actions}>
        {numSelected > 0 ? (
          <Tooltip title="Delete">
            <IconButton aria-label="Delete">
              <DeleteIcon onClick={() => { if (window.confirm('Are you sure you wish to delete '+numSelected +' item?')) deleteUser() } }>

              </DeleteIcon>
            </IconButton>
          </Tooltip>
        ) : (
          <Tooltip title="Filter list">
            <IconButton aria-label="Filter list">
              <FilterListIcon />
            </IconButton>
          </Tooltip>
        )}
      </div>
    </Toolbar>
  );
};

EnhancedTableToolbar.propTypes = {
  classes: PropTypes.object.isRequired,
  numSelected: PropTypes.number.isRequired,
  selectedArray: PropTypes.array.isRequired,
};

EnhancedTableToolbar = withStyles(toolbarStyles)(EnhancedTableToolbar);

This is my user class. The toolbar is used in this class. I want the deleteUser() get triggered when the toolbar delete button is clicked.

class User extends React.Component {
    constructor(props) {
            super(props);
            this.state = initialState;
            this.handleChange = this.handleChange.bind(this);
            this.handleSubmit = this.handleSubmit.bind(this);
          }

    reset() {
        this.setState(initialState);
    }   

    componentDidMount() {
            axios.get("http://localhost:4000/readUsers")
              .then(json => {
                this.setState({data: json.data});
                console.log({json})
              }).catch(err => console.log("error:   "+err));
    }

    deleteUser(){

    }


    displayUsers(){
        const { classes } = this.props;
        const { data, order, orderBy, selected, rowsPerPage, page } = this.state;
        const emptyRows = rowsPerPage - Math.min(rowsPerPage, data.length - page * rowsPerPage);
        console.log("selected length:  "+selected.length+" selected:  "+selected);
        return(
        <Paper className={classes.root}>
        <EnhancedTableToolbar numSelected={selected.length} selectedArray={selected} />
        <div className={classes.tableWrapper}>
          <Table className={classes.table} aria-labelledby="tableTitle">
            <EnhancedTableHead
              numSelected={selected.length}
              order={order}
              orderBy={orderBy}
              onSelectAllClick={this.handleSelectAllClick}
              onRequestSort={this.handleRequestSort}
              rowCount={data.length}
            />
            <TableBody>
              {stableSort(data, getSorting(order, orderBy))
                .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
                .map(n => {
                  const isSelected = this.isSelected(n.id);
                  return (
                    <TableRow
                      hover
                      onClick={event => this.handleClick(event, n.id)}
                      role="checkbox"
                      aria-checked={isSelected}
                      tabIndex={-1}
                      key={n.id}
                      selected={isSelected}
                    >
                      <TableCell padding="checkbox">
                        <Checkbox checked={isSelected} />
                      </TableCell>
                      <TableCell component="th" scope="row" padding="none">
                        {n.id}
                      </TableCell>
                      <TableCell align="right">{n.name}</TableCell>
                      <TableCell align="right">{n.username}</TableCell>
                      <TableCell align="right">{n.email}</TableCell>
                      <TableCell align="right">{n.address}</TableCell>
                    </TableRow>
                  );

                })}
              {emptyRows > 0 && (
                <TableRow style={{ height: 49 * emptyRows }}>
                  <TableCell colSpan={6} />
                </TableRow>
              )}
            </TableBody>
          </Table>
        </div>
        <TablePagination
          rowsPerPageOptions={[5, 10, 25]}
          component="div"
          count={data.length}
          rowsPerPage={rowsPerPage}
          page={page}
          backIconButtonProps={{
            'aria-label': 'Previous Page',
          }}
          nextIconButtonProps={{
            'aria-label': 'Next Page',
          }}
          onChangePage={this.handleChangePage}
          onChangeRowsPerPage={this.handleChangeRowsPerPage}
        />
      </Paper>
      );
  } 

  handleRequestSort = (event, property) => {
    const orderBy = property;
    let order = 'desc';

    if (this.state.orderBy === property && this.state.order === 'desc') {
      order = 'asc';
    }

    this.setState({ order, orderBy });
  };

  handleSelectAllClick = event => {
    if (event.target.checked) {
      this.setState(state => ({ selected: state.data.map(n => n.id) }));
      return;
    }
    this.setState({ selected: [] });
  };

  handleClick = (event, id) => {
    const { selected } = this.state;
    const selectedIndex = selected.indexOf(id);
    let newSelected = [];

    if (selectedIndex === -1) {
      newSelected = newSelected.concat(selected, id);
    } else if (selectedIndex === 0) {
      newSelected = newSelected.concat(selected.slice(1));
    } else if (selectedIndex === selected.length - 1) {
      newSelected = newSelected.concat(selected.slice(0, -1));
    } else if (selectedIndex > 0) {
      newSelected = newSelected.concat(
        selected.slice(0, selectedIndex),
        selected.slice(selectedIndex + 1),
      );
    }

    this.setState({ selected: newSelected });
  };

  handleChangePage = (event, page) => {
    this.setState({ page });
  };

  handleChangeRowsPerPage = event => {
    this.setState({ rowsPerPage: event.target.value });
  };

  isSelected = id => this.state.selected.indexOf(id) !== -1;

  render() {
      const { classes } = this.props;
    return (
    <GridContainer>
            <GridItem xs={12} sm={12} md={12}>
            {this.checkCurrentButton()}
            <Card>
            <CardHeader color="primary">
                <h4 className={classes.cardTitleWhite}>User List</h4>
                <p className={classes.cardCategoryWhite}>
                {}
                </p>
            </CardHeader>
            <CardBody>
            {this.displayUser()}
            </CardBody>
            <CardFooter>

            </CardFooter>
            </Card>
            </GridItem>
        </GridContainer>

    );
  }
}

User.propTypes = {
  classes: PropTypes.object.isRequired,
};

3 Answers 3

2

You can just pass the function as a prop to the toolbar from your parent class and then access it like any other prop with this.props.deleteUser() like so:

let EnhancedTableToolbar = props => {
const { numSelected, classes, selectedArray } = props;
  return (
    <Toolbar
      className={classNames(classes.root, {
        [classes.highlight]: numSelected > 0,
      })}
    >
      <div className={classes.title}>
        {numSelected > 0 ? (
          <Typography color="inherit" variant="subtitle1">
            {numSelected} selected
          </Typography>
        ) : (
          <Typography variant="h6" id="tableTitle">
            User List
          </Typography>
        )}
      </div>
      <div className={classes.spacer} />
      <div className={classes.actions}>
        {numSelected > 0 ? (
          <Tooltip title="Delete">
            <IconButton aria-label="Delete">
              <DeleteIcon onClick={() => { if (window.confirm('Are you sure you wish to delete '+numSelected +' item?')) this.props.deleteUser() } }>

              </DeleteIcon>
            </IconButton>
          </Tooltip>
        ) : (
          <Tooltip title="Filter list">
            <IconButton aria-label="Filter list">
              <FilterListIcon />
            </IconButton>
          </Tooltip>
        )}
      </div>
    </Toolbar>
  );
};

EnhancedTableToolbar.propTypes = {
  classes: PropTypes.object.isRequired,
  numSelected: PropTypes.number.isRequired,
  selectedArray: PropTypes.array.isRequired,
};

EnhancedTableToolbar = withStyles(toolbarStyles)(EnhancedTableToolbar);

And your User Class:

class User extends React.Component {
    constructor(props) {
            super(props);
            this.state = initialState;
            this.handleChange = this.handleChange.bind(this);
            this.handleSubmit = this.handleSubmit.bind(this);
          }

    reset() {
        this.setState(initialState);
    }   

    componentDidMount() {
            axios.get("http://localhost:4000/readUsers")
              .then(json => {
                this.setState({data: json.data});
                console.log({json})
              }).catch(err => console.log("error:   "+err));
    }

    deleteUser(){

    }


    displayUsers(){
        const { classes } = this.props;
        const { data, order, orderBy, selected, rowsPerPage, page } = this.state;
        const emptyRows = rowsPerPage - Math.min(rowsPerPage, data.length - page * rowsPerPage);
        console.log("selected length:  "+selected.length+" selected:  "+selected);
        return(
        <Paper className={classes.root}>
        <EnhancedTableToolbar deleteUser={this.deleteUser} numSelected={selected.length} selectedArray={selected} />
        <div className={classes.tableWrapper}>
          <Table className={classes.table} aria-labelledby="tableTitle">
            <EnhancedTableHead
              numSelected={selected.length}
              order={order}
              orderBy={orderBy}
              onSelectAllClick={this.handleSelectAllClick}
              onRequestSort={this.handleRequestSort}
              rowCount={data.length}
            />
            <TableBody>
              {stableSort(data, getSorting(order, orderBy))
                .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
                .map(n => {
                  const isSelected = this.isSelected(n.id);
                  return (
                    <TableRow
                      hover
                      onClick={event => this.handleClick(event, n.id)}
                      role="checkbox"
                      aria-checked={isSelected}
                      tabIndex={-1}
                      key={n.id}
                      selected={isSelected}
                    >
                      <TableCell padding="checkbox">
                        <Checkbox checked={isSelected} />
                      </TableCell>
                      <TableCell component="th" scope="row" padding="none">
                        {n.id}
                      </TableCell>
                      <TableCell align="right">{n.name}</TableCell>
                      <TableCell align="right">{n.username}</TableCell>
                      <TableCell align="right">{n.email}</TableCell>
                      <TableCell align="right">{n.address}</TableCell>
                    </TableRow>
                  );

                })}
              {emptyRows > 0 && (
                <TableRow style={{ height: 49 * emptyRows }}>
                  <TableCell colSpan={6} />
                </TableRow>
              )}
            </TableBody>
          </Table>
        </div>
        <TablePagination
          rowsPerPageOptions={[5, 10, 25]}
          component="div"
          count={data.length}
          rowsPerPage={rowsPerPage}
          page={page}
          backIconButtonProps={{
            'aria-label': 'Previous Page',
          }}
          nextIconButtonProps={{
            'aria-label': 'Next Page',
          }}
          onChangePage={this.handleChangePage}
          onChangeRowsPerPage={this.handleChangeRowsPerPage}
        />
      </Paper>
      );
  } 

  handleRequestSort = (event, property) => {
    const orderBy = property;
    let order = 'desc';

    if (this.state.orderBy === property && this.state.order === 'desc') {
      order = 'asc';
    }

    this.setState({ order, orderBy });
  };

  handleSelectAllClick = event => {
    if (event.target.checked) {
      this.setState(state => ({ selected: state.data.map(n => n.id) }));
      return;
    }
    this.setState({ selected: [] });
  };

  handleClick = (event, id) => {
    const { selected } = this.state;
    const selectedIndex = selected.indexOf(id);
    let newSelected = [];

    if (selectedIndex === -1) {
      newSelected = newSelected.concat(selected, id);
    } else if (selectedIndex === 0) {
      newSelected = newSelected.concat(selected.slice(1));
    } else if (selectedIndex === selected.length - 1) {
      newSelected = newSelected.concat(selected.slice(0, -1));
    } else if (selectedIndex > 0) {
      newSelected = newSelected.concat(
        selected.slice(0, selectedIndex),
        selected.slice(selectedIndex + 1),
      );
    }

    this.setState({ selected: newSelected });
  };

  handleChangePage = (event, page) => {
    this.setState({ page });
  };

  handleChangeRowsPerPage = event => {
    this.setState({ rowsPerPage: event.target.value });
  };

  isSelected = id => this.state.selected.indexOf(id) !== -1;

  render() {
      const { classes } = this.props;
    return (
    <GridContainer>
            <GridItem xs={12} sm={12} md={12}>
            {this.checkCurrentButton()}
            <Card>
            <CardHeader color="primary">
                <h4 className={classes.cardTitleWhite}>User List</h4>
                <p className={classes.cardCategoryWhite}>
                {}
                </p>
            </CardHeader>
            <CardBody>
            {this.displayUser()}
            </CardBody>
            <CardFooter>

            </CardFooter>
            </Card>
            </GridItem>
        </GridContainer>

    );
  }
}

User.propTypes = {
  classes: PropTypes.object.isRequired,
};
Sign up to request clarification or add additional context in comments.

Comments

1

You need to pass the deleteUser function from your parent component to the child component. You can do this in the props. You're calling the EnhancedTableToolbar inside of the displayUsers method, so in it do the following:

 return(
    <Paper className={classes.root}>
    <EnhancedTableToolbar 
            numSelected={selected.length} 
            selectedArray={selected}
            deleteUser={this.deleteUser} // you pass the deleteUser of the parent component to the EnhancedTableToolbar as a prop
    />

Then use it inside of the EnhancedTableToolbar

<IconButton aria-label="Delete">
 <DeleteIcon onClick={() => { if (window.confirm('Are you sure you wish to delete '+numSelected +' item?')) this.props.deleteUser() } }>
</DeleteIcon>

Comments

0

Your Toolbar component has to receive a property such as onDeleteUser

This way the parent can give the Toolbar a way for it to “call back” when something such as a click happened.

So Toolbar will do something like onClick={this.props.onDeleteUser} When someone clicks and that event fires, the function is called and the Parent can delete the user.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.