【问题标题】:Changing styles during clicking在单击期间更改样式
【发布时间】:2019-05-10 03:36:37
【问题描述】:



我有 ReactJS 项目,我想在单击期间更改按钮的颜色。我知道它是一个 Ripple API,但使用它非常难以理解。有人可以告诉我该怎么做吗?

我尝试创建两个元素 - 父元素和子元素 - 并在单击时将子元素的背景更改为透明。不幸的是,如果按钮处于活动状态并且它只是不工作,我还有负责更改类的“类”对象。 我的代码如下:

import React, { Component } from 'react';
import { withStyles } from '@material-ui/core/styles';
import Button from '@material-ui/core/Button';
import PropTypes from 'prop-types';
import styles from './MydButton.style';

class MyButton extends Component {
  constructor(props) {
    super(props);
    this.state = {
      isClicked: false
    };
  }

  handleClick = () => {
    this.setState({ isClicked: !this.state.isClicked });
  }

  render() {
    const {
      classes,
      children,
      color,
      disabled,
      className,
      onClick,
      type,
      border,
      ...props
    } = this.props;

    const myClass = this.state.isClicked ? 'auxClass' : 'buttonDefaultRoot';


    return (
      <div className={classes.parentRoot} >
        <Button
          classes={{
            root: disabled
            ? classes.buttonDisabledRoot
            : classes.buttonRoot,
            label: disabled 
            ? classes.buttonLabelDisabled 
            : classes.buttonLabel,
          }}
          {...props}
          onClick={this.handleClick}
          className={myClass}
          disabled={disabled}
          type={type === undefined ? 'button' : type}
        >
          {children}
        </Button>
      </div>
    )
  }
};

MyButton.propTypes = {
  children: PropTypes.string.isRequired,
  disabled: PropTypes.bool,
  classes: PropTypes.object.isRequired,
};

MyButton.defaultProps = {
  disabled: false,
};

export default withStyles(styles)(MyButton);

和样式:

    const buttonRoot = {
      border: 0,
      height: 48,
      width: '100%',
    }


export default theme => ({
  buttonDefaultRoot: {
    ...buttonRoot,
    transition: 'all 1s ease-in-out',
    backgroundImage: 'linear-gradient(to right, #F59C81, #E65DA2, #E65DA2, #B13A97, #881E8E)',
    boxShadow: '0px 1px 3px rgba(0, 0, 0, 0.16)',
    backgroundSize: '300% 100%',
    marginTop: 0,
    '&:hover': {
      backgroundPosition: '100% 0%',
      transition: 'all 1s ease-in-out',
    }
  },

  parentRoot: {
       ...buttonRoot,
       backgroundColor: 'red',   
       backgroundSize: '300% 100%',
        marginTop: 36,
      }, 

      auxClass: {
        backgroundImage: 'none',
      },

【问题讨论】:

    标签: css reactjs button frontend material-ui


    【解决方案1】:

    ReactJS 的 Material UI 核心

    文档非常好。我已经更新了我的答案以适应这个问题的具体需求。我还为偶然发现这个问题的人提供了两个通用解决方案。

    量身定制的解决方案:

    将按钮的背景颜色从classes.buttonDefaultRoot(由问题所有者定义的颜色)更改为由该问题所有者定义的渐变。

    第一步,在状态中存储一个变量。您可以随意调用它,但我调用的是 bgButton。将其设置为this.props.classes.buttonDefaultRoot,如下所示:

    state = {
      bgButton: this.props.classes.buttonDefaultRoot,
    }
    

    接下来,您要定义处理点击的函数。再一次,把它称为你想要的。我会称之为handleClick

    handleClick = () => {
        const { classes } = this.props; //this grabs your css style theme
        this.setState({ bgButton: classes.parentRoot.auxClass }); //accessing styles
      };
    

    这里发生了几件事。首先,我正在解构道具。所以,我正在创建一个名为classes 的新const 变量,它的值与this.props.classes 相同。 classes 包含一组对象,这些对象定义了您的按钮、边距等的 css 样式。您可以访问这些样式,就像您尝试获取 obj 中道具的值一样。

    在这种情况下,您可以通过 classes.buttonDefaultRoot 访问您的按钮样式。这会照顾您的手柄点击功能。

    最后一步:渲染按钮。在您的渲染方法中,您想从状态中获取bgButton,如下所示:

    render() {
      const { bgButton } = this.state; 
    

    然后您想将按钮的className 分配给bgButton 并像这样添加onClick 功能(这遵循Material UI Core 文档):

    <Button variant="contained" color="primary" className={classNames(bgButton)} onClick={this.handleClick}>Button Name</Button>
    

    把它们放在一起你会得到这个:

    import React, { Component } from "react";
    import Button from "@material-ui/core/Button";
    import PropTypes from "prop-types";
    import classNames from "classnames";
    import { withStyles } from "@material-ui/core/styles";
    
    export default theme => ({ ... }) //not going to copy all of this
    
    class MyButton extends Component {
      state = {
        bgButton: null
      };
      handleClick = () => {
        const { classes } = this.props;
        this.setState({ bgButton: classes.parentRoot.auxClass });
      };
      render() {
        const { bgButton } = this.state;
        return (
          <div className={classes.container}>
            <Button
              variant="contained"
              color="primary"
              className={classNames(bgButton)}
              onClick={this.handleClick}
            >
              Custom CSS
            </Button>
          </div>
        );
      }
    }
    
    MyButton.propTypes = {
      classes: PropTypes.object.isRequired
    };
    
    export default withStyles(styles)(MyButton);
    

    一般解决方案

    此解决方案适用于那些想要使用预定义颜色的人,即默认、主要、次要、继承。此实现不需要 PropTypes 或 className 导入。这会将颜色从预定义的蓝色更改为预定义的粉红色。而已。

    state = {
      bgButton: "primary", 
    } 
    handleClick = () => {
      this.setState({ bgButton: "secondary" }); 
    } 
    
    render() {
      const { bgButton } = this.state; 
      return(
       ...
       <Button
         onClick = {this.handleClick} 
         variant = "contained" //checked Material UI documentation
         color={bgButton}
        > ..etc.
    

    一般解决方案 2

    要使您的自定义样式适应按钮,您必须导入 PropTypes 和 classNames 并采用与上述定制解决方案类似的方法。这里唯一的区别是我的语法和类名。我正在密切关注此处的文档,因此您可以轻松地跟进并在必要时重新调整。

        import React, { Component } from "react";
        import Button from "@material-ui/core/Button";
        import PropTypes from "prop-types";
        import classNames from "classnames";
        import { withStyles } from "@material-ui/core/styles";
        import purple from "@material-ui/core/colors/purple";
    
        const styles = theme => ({
          container: {
            display: "flex",
            flexWrap: "wrap"
          },
          margin: {
            margin: theme.spacing.unit
          },
          cssRoot: {
            color: theme.palette.getContrastText(purple[500]),
            backgroundColor: purple[500],
            "&:hover": {
              backgroundColor: purple[700]
            }
          },
          bootstrapRoot: {
            boxShadow: "none",
            textTransform: "none",
            fontSize: 16,
            padding: "6px 12px",
            border: "1px solid",
            backgroundColor: "#007bff",
            borderColor: "#007bff",
            fontFamily: [
              "-apple-system",
              "BlinkMacSystemFont",
              '"Segoe UI"',
              "Roboto",
              '"Helvetica Neue"',
              "Arial",
              "sans-serif",
              '"Apple Color Emoji"',
              '"Segoe UI Emoji"',
              '"Segoe UI Symbol"'
            ].join(","),
            "&:hover": {
              backgroundColor: "#0069d9",
              borderColor: "#0062cc"
            },
            "&:active": {
              boxShadow: "none",
              backgroundColor: "#0062cc",
              borderColor: "#005cbf"
            },
            "&:focus": {
              boxShadow: "0 0 0 0.2rem rgba(0,123,255,.5)"
            }
          }
        });
    
        class MyButton extends Component {
          state = {
            bgButton: null
          };
          handleClick = () => {
            const { classes } = this.props;
            this.setState({ bgButton: classes.cssRoot });
          };
          render() {
            const { classes } = this.props; //this gives you access to all styles defined above, so in your className prop for your HTML tags you can put classes.container, classes.margin, classes.cssRoot, or classes.bootstrapRoot in this example. 
            const { bgButton } = this.state;
            return (
              <div className={classes.container}>
                <Button
                  variant="contained"
                  color="primary"
                  className={classNames(bgButton)}
                  onClick={this.handleClick}
                >
                  Custom CSS
                </Button>
              </div>
            );
          }
        }
    MyButton.propTypes = {
      classes: PropTypes.object.isRequired
    };
    
    export default withStyles(styles)(MyButton);
    

    小费。您不再需要构造函数或绑定方法。

    希望这会有所帮助。

    【讨论】:

    • 感谢您对该主题的关注。不幸的是,它也不起作用。单击时背景颜色不会改变。而且我相信渲染方法之后应该是道具,而不是状态,对吗? render() { const { bgButton } = this.state;
    • 确定答案有帮助吗?还是你还卡住了?
    • 我还是卡住了。
    • 您遇到错误了吗?还是只是不改变颜色?
    • 抱歉刚刚看到你更新的评论...给我一秒钟在我的本地机器上测试这个
    猜你喜欢
    • 2018-04-23
    • 1970-01-01
    • 1970-01-01
    • 2019-10-28
    • 2021-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-17
    相关资源
    最近更新 更多