在React中切换类

时间:2016-04-04 12:47:24

标签: javascript reactjs

我正在使用一个项目,我有一个菜单按钮。

<a ref="btn" href="#" className="btn-menu show-on-small"><i></i></a>

Sidenav组件如:

<Sidenav ref="menu" />

我编写了以下代码来切换菜单:

class Header extends React.Component {

    constructor(props){
        super(props);
        this.toggleSidenav = this.toggleSidenav.bind(this);
    }

    render() {
        return (
          <div className="header">
            <i className="border hide-on-small-and-down"></i>
            <div className="container">
          <a ref="btn" href="#" className="btn-menu show-on-small"><i></i></a>
          <Menu className="menu hide-on-small-and-down"/>
          <Sidenav />
        </div>
          </div>
        )
    }

    toggleSidenav() {
        this.refs.btn.classList.toggle('btn-menu-open');
    }

    componentDidMount() {
        this.refs.btn.addEventListener('click', this.toggleSidenav);
    }

    componentWillUnmount() {
        this.refs.btn.removeEventListener('click', this.toggleSidenav);
    }
}

问题是this.refs.sidenav不是DOM元素,我不能在他身上添加一个类。

有人可以解释一下如何切换Sidenav组件上的课程,就像我在按钮上一样吗?

5 个答案:

答案 0 :(得分:21)

如果希望React正确有效地呈现DOM,则必须使用组件的State来更新组件参数,例如Class Name。

更新:我更新了示例以点击按钮切换Sidemenu。这不是必需的,但你可以看到它是如何工作的。您可能需要使用“this.state”与“this.props”,如我所示。我习惯使用Redux组件。

constructor(props){
    super(props);
}

getInitialState(){
  return {"showHideSidenav":"hidden"};
}

render() {
    return (
        <div className="header">
            <i className="border hide-on-small-and-down"></i>
            <div className="container">
                <a ref="btn" onClick={this.toggleSidenav.bind(this)} href="#" className="btn-menu show-on-small"><i></i></a>
                <Menu className="menu hide-on-small-and-down"/>
                <Sidenav className={this.props.showHideSidenav}/>
            </div>
        </div>
    )
}

toggleSidenav() {
    var css = (this.props.showHideSidenav === "hidden") ? "show" : "hidden";
    this.setState({"showHideSidenav":css});
}

现在,当您切换状态时,组件将更新并更改sidenav组件的类名。您可以使用CSS来显示/隐藏使用类名称的sidenav。

.hidden {
   display:none;
}
.show{
   display:block;
}

答案 1 :(得分:11)

refs不是DOM元素。为了找到DOM元素,您需要先使用findDOMNode menthod。

做,这个

var node = ReactDOM.findDOMNode(this.refs.btn);
node.classList.toggle('btn-menu-open');

或者,您可以像这样使用(几乎是实际代码)

this.state.styleCondition = false;


<a ref="btn" href="#" className={styleCondition ? "btn-menu show-on-small" : ""}><i></i></a>

然后,您可以根据州的状态变化条件更改styleCondition

答案 2 :(得分:3)

Ori Drori的评论是正确的,你不是这样做的“React Way”。在React中,理想情况下,您不应该使用DOM更改类和事件处理程序。在React组件的render()方法中执行;在这种情况下,这将是sideNav和你的标题。如何在代码中完成此操作的粗略示例如下。

HEADER

class Header extends React.Component {
constructor(props){
    super(props);
}

render() {
    return (
        <div className="header">
            <i className="border hide-on-small-and-down"></i>
            <div className="container">
                <a ref="btn" href="#" className="btn-menu show-on-small"
                onClick=this.showNav><i></i></a>
                <Menu className="menu hide-on-small-and-down"/>
                <Sidenav ref="sideNav"/>
            </div>
        </div>
    )
}

showNav() {
  this.refs.sideNav.show();
}
}

SIDENAV

 class SideNav extends React.Component {
   constructor(props) {
     super(props);
     this.state = {
       open: false
     }
   }

   render() {
     if (this.state.open) {
       return ( 
         <div className = "sideNav">
            This is a sidenav 
         </div>
       )
     } else {
       return null;
     }

   }

   show() {
     this.setState({
       open: true
     })
   }
 }

你可以在这里看到我们不是在切换类,而是使用组件的状态来渲染SideNav。这种方式或类似方式是使用反应的整个前提。如果您使用的是bootstrap,那么有一个库将引导元素与反应方式集成在一起,允许您使用相同的元素,但在它们上设置状态而不是直接操作DOM。它可以在这里找到 - https://react-bootstrap.github.io/

希望这有帮助,并享受使用React!

答案 3 :(得分:2)

在React中切换功能

首先,您应该创建构造函数 像这样

constructor(props) {
        super(props);
        this.state = {
            close: true,
        };
    }

然后创建一个像这样的函数

yourFunction = () => {
        this.setState({
            close: !this.state.close,
        });
    };

然后像这样使用

render() {
        const {close} = this.state;
        return (

            <Fragment>

                 <div onClick={() => this.yourFunction()}></div>

                 <div className={close ? "isYourDefaultClass" : "isYourOnChangeClass"}></div>

            </Fragment>
        )
    }
}

请提供更好的解决方案

答案 4 :(得分:0)

对于任何在2019年阅读此书的人,在发布React 16.8之后,请查看React Hooks。它确实简化了组件中的处理状态。这些文档写得很好,并附带了您所需要的示例。