Подтвердить что ты не робот

Переключить класс в реале

Я использую реакцию для проекта, где у меня есть кнопка меню.

<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, как на моей кнопке?

4b9b3361

Ответ 1

Вы должны использовать состояние компонента для обновления параметров компонента, таких как имя класса, если вы хотите, чтобы React визуализировал вашу DOM правильно и эффективно.

UPDATE: я обновил пример, чтобы переключить 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;
}

Ответ 2

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 на основе условий изменения состояния.

Ответ 3

Комментарии Ори Дрири верны, вы не делаете этого "Реагировать". В React лучше не менять классы и обработчики событий с помощью DOM. Сделайте это в методе render() ваших компонентов React; в этом случае это будет sideNav и ваш заголовок. Примерный пример того, как это будет выполняться в вашем коде, выглядит следующим образом.

ЗАГОЛОВОК

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!