Как переключать класс в вложенный компонент в ReactJS
-
21-12-2019 - |
Вопрос
У меня есть такой рендер () метод в моем корневом компонент:
render: function() {
return (
<div className="question">
<QuestionA question={this.props.question} author={this.props.author}/>
<QuestionB yes={this.state.yes} no={this.state.no} />
<div className="question-side-switcher" onClick={this.handleSideChanging}></div>
</div>
);
}
.
Откуда я хочу переключить «активный» класс между вопросами и компонентами вопросов, когда пользователь нажимал кнопку.Как я могу это сделать?Имейте в виду, что вопрос и вопрос передач устанавливают свои собственные классы в своих методах Render ().Например, редандиация рецентов ():
render: function() {
return (
<section className="question-b-container">
...
</section>
);
}
. Решение
Есть пара параметров, которыми вы могли бы справиться с этим.
Если вы хотите, чтобы родитель контролирует дополнительный класс, вы можете просто передать его в детские компоненты и у них добавить его к существующему имени класса ( jsfiddle demo ):
var QuestionA = React.createClass({
render: function() {
return <section className={this.props.className + " question-a-container"}>Section A</section>;
}
});
var QuestionB = React.createClass({
render: function() {
return <section className={this.props.className + " question-b-container"}>Section B</section>;
}
});
var Root = React.createClass({
getInitialState: function() {
return { question: 'a' };
},
render: function() {
var qAclassName = this.state.question === 'a' ? 'active' : '';
var qBclassName = this.state.question === 'b' ? 'active' : '';
return (
<div className="question">
<QuestionA className={qAclassName} />
<QuestionB className={qBclassName} />
<div className="question-side-switcher" onClick={this.handleSideChanging}>Change</div>
</div>
);
},
handleSideChanging: function() {
this.setState({question: this.state.question === 'a' ? 'b' : 'a' });
}
});
.
Однако, вероятно, имеет больше смысла позволить ребенку управлять именем класса, и просто отправлять некоторые данные, чтобы указать, что он должен установить свой активный класс ( jsfiddle demo ):
// Using classSet to more easily create conditional class names;
// see http://facebook.github.io/react/docs/class-name-manipulation.html
var cx = React.addons.classSet;
var QuestionA = React.createClass({
render: function() {
// always set "question-a-container";
// set "active" if we got a truthy prop named `active`
var className = cx({
"question-a-container": true,
"active": this.props.active
});
return <section className={className}>Section A</section>;
}
});
var QuestionB = React.createClass({
render: function() {
// always set "question-b-container";
// set "active" if we got a truthy prop named `active`
var className = cx({
"question-b-container": true,
"active": this.props.active
});
return <section className={className}>Section B</section>;
}
});
var Root = React.createClass({
getInitialState: function() {
return { question: 'a' };
},
render: function() {
return (
<div className="question">
{/* For each question, compare to state to see if it's active. */}
<QuestionA active={this.state.question === 'a'} />
<QuestionB active={this.state.question === 'b'} />
<div className="question-side-switcher" onClick={this.handleSideChanging}>Change</div>
</div>
);
},
handleSideChanging: function() {
this.setState({question: this.state.question === 'a' ? 'b' : 'a' });
}
});
. Другие советы
as as Brian Voelker упомянул его в Комментарии , теперь официальный способ манипулировать классами в реакции - использовать Утилита классов .
Вы можете определить ваши два компонента, как так:
import React, { Component } from 'react'
import classNames from 'classnames'
class QuestionA extends Component {
render () {
const { active } = this.props
const cx = classNames('question-a-container', { active })
return (
<section className={cx}></section>
)
}
}
.
и просто пропустите их генеракодицетагкод, чтобы переключить динамичный класс.
У меня была проблема, похожая на это, я создал планшетный ящик, и я оказал только компонент, запрошенный с помощью таблетки, но такое решение не было идеальным, так как я терял состояние дочернего компонента, когда я переключился на другой стаблетка.
Чтобы избежать этого в рендере, я называю функцию, чтобы сделать все мои ребенка, в этой функции я обрушу каждого ребенка в div, и я назначаю необходимое имя пользователя для div, в моем случае мне нужно отобразить один компонентВремя, так что я использовал дисплей: блок или ни один в зависимости от кнопки нажал.
renderMyChilds() {
var renderedComponents = this.props.children.map(function(child, _key) {
if(this.state.drawerOpened == true) {
var ElementToRender = child;
var MyElement = (this.state.buttonSelected != _key) ? <div className="hiddenComponent"><ElementToRender /></div> : <div><ElementToRender /></div>;
} else {
var ElementToRender = child;
var MyElement = <div><ElementToRender className="hiddenComponent" /></div>;
}
return (MyElement);
}, this);
return renderedComponents;
}
.
.hiddencomponent { Дисплей: нет; }
.visiblecomponent { Дисплей: блок; }