类如何调用其他类函数?

时间:2019-04-04 06:10:12

标签: javascript reactjs function class

我是新来的反应和JavaScript。我可以知道如何从当前类中调用其他类函数吗?

我只能使用prop在类之间传递数据。

例如,我有一个工具栏和一个用户类。当我单击工具栏上的删除按钮时。我想在用户类中调用delete函数。如何实现呢?

这是我的工具栏。当我单击删除按钮时,我想在我的用户类中触发deleteUser。

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);

这是我的用户类别。该类中使用了工具栏。我希望在单击工具栏的删除按钮时触发deleteUser()。

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 个答案:

答案 0 :(得分:2)

您可以将函数作为道具从父类传递到工具栏,然后像其他任何道具一样使用this.props.deleteUser()进行访问,如下所示:

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);

以及您的用户类别:

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,
};

答案 1 :(得分:1)

您需要将deleteUser函数从父组件传递到子组件。您可以在道具中执行此操作。您正在EnhancedTableToolbar方法内调用displayUsers,因此请执行以下操作:

 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
    />

然后在EnhancedTableToolbar

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

答案 2 :(得分:0)

您的工具栏组件必须接收诸如 onDeleteUser

之类的属性。

通过这种方式,父母可以为工具栏提供一种方法,使其在发生诸如点击之类的事件时可以“回调”。

因此,工具栏将执行类似onClick = {this.props.onDeleteUser}的操作 当某人单击并触发该事件时,将调用该函数,并且父级可以删除用户。