使用Gatsby Js

时间:2018-04-04 22:01:06

标签: javascript css reactjs styled-components gatsby

我正在使用GatsbyJs并尝试完成一个活动的类切换。我有一个简单的组件,由一个内部有跨度的锚标签组成。我想通过在点击时锚点上切换活动类来更改某些css。这是我到目前为止的代码,我也使用样式组件。我在下面的破解代码部分尝试了一些vanilla js,这显然不起作用,因此破坏了代码。

提前致谢

样式

const Menu = styled.a`
  position: absolute;
  cursor: pointer; padding: 10px 35px 16px 0px;
  span, span:before, span:after{
    cursor: pointer;
    border-radius: 1px;
    height: 5px;
    width: 35px;
    background: #000000;
    position: absolute;
    display: block;
    content: '';
    transition: all 200ms ease-in-out;
  }
  span:before{
    top: -10px; 
  }
  span:after{
    bottom: -10px; 
  }
  .active span{
    background-color: transparent;
  }
  .active span:before, .active span:after{
    top:0;
  }
  .active span:before{
    transform: rotate(45deg);
  }
  .active span:after{
    transform: rotate(-45deg);
  }
`

成分<​​/ P>

const TemplateWrapper = ({ children }) => (
  <div>
    <Wrapper>
      <Menu id="nav-toggle" className="menu"><span></span></Menu>
      {children()}
    </Wrapper>       
  </div>
)

TemplateWrapper.propTypes = {
  children: PropTypes.func,
}

export default TemplateWrapper

破码

document.querySelector( "#nav-toggle" )
  .addEventListener( "click", function() {
    this.classList.toggle( "active" );
  });

这是呈现的html

<a class="menu sc-bwzfXH SqHLW" id="nav-toggle"><span></span></a>

2 个答案:

答案 0 :(得分:1)

您可以使用组件state来管理此问题。 代码如下:

已更新:将逻辑移至Menu组件,因为将其放置在那里更有意义。下面的工作示例

class Menu extends React.Component {

  constructor(props) {
    super(props);
    
    this.menuClick = this.menuClick.bind(this);
    this.state = {
      menuClass: '',
    }
  }
  
  menuClick(e) {
    const menuClass = this.state.menuClass === '' ? 'active' : '';
    this.setState({ menuClass });
  }
  
  render() {
    const {children, id} = this.props;
    const menuClassName = `menu sc-bwzfXH SqHLW nav-toggle ${this.state.menuClass}`;
    
    return (<a className={menuClassName} id={id} onClick={this.menuClick}>{children}</a>);

  }
}

ReactDOM.render(<Menu><span>Test link</span></Menu>,  document.getElementById('menu'))
.menu {
  font-weight: bolder;
  color: blue;
 }
 
.active{
  color:red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="menu" />

答案 1 :(得分:1)

好的,你可以看看REACT - toggle class onclick 。有几个答案显示了如何实现这一目标的方式,但是当您想要使用多个类时,事情会变得更加混乱。

我喜欢这个包来处理基于道具或状态处理多个类的样式的情况:https://github.com/JedWatson/classnames

为了清楚这个答案,我简化了样式,并假设menu是一个全局类,你也想要应用。

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import styled from 'styled-components';

const Wrapper = styled.div``;

const Menu = styled.a`
  span {
    color: green;
  }
  &.active span {
    color: blue;
  }
`;

class TemplateWrapper extends Component {
  state = {
    isActive: false
  };

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

  render() {
    const menuClass = classNames({
      menu: true,
      active: this.state.isActive
    });

    return (
      <Wrapper>
        <Menu id="nav-toggle" className={menuClass} onClick={this.handleClick}>
          <span>Test</span>
        </Menu>
        {this.props.children}
      </Wrapper>
    );
  }
}

TemplateWrapper.propTypes = {
  children: PropTypes.node
};

TemplateWrapper.defaultProps = {
  children: null
};

export default TemplateWrapper;

注意.active之前的&符号(&amp;)。如docs中所述,styled components支持所有CSS加上嵌套。

  

&符号(&amp;)被我们为该样式化组件生成的唯一类名替换,从而可以轻松获得复杂的逻辑。

但是,通过充分利用styled components功能,您可以在没有classnames的情况下实现相同的效果。请查看文档的section

需要进行一些更改:

const Menu = styled.a`
  span {
    color: ${props => (props.active ? 'blue' : 'green')};
  }
`;

渲染方法看起来像这样:

render() {
  return (
    <Wrapper>
      <Menu id="nav-toggle" className="menu" active={this.state.isActive} onClick={this.handleClick}>
        <span>Test</span>
      </Menu>
      {this.props.children}
    </Wrapper>
  );
}