Ich versuche herauszufinden, wie eine aktive Klasse umgeschaltet werden kann onClick
, um die CSS-Eigenschaften zu ändern.
Ich habe viele Ansätze gewählt und viele SO-Antworten gelesen. Mit jquery wäre es relativ einfach, aber ich kann nicht herausfinden, wie man das mit reagieren macht. Mein Code ist unten. Kann mir jemand raten, wie ich das machen soll?
Ist dies möglich, ohne für jedes Element eine neue Komponente zu erstellen?
class Test extends Component(){
constructor(props) {
super(props);
this.addActiveClass= this.addActiveClass.bind(this);
}
addActiveClass() {
//not sure what to do here
}
render() {
<div>
<div onClick={this.addActiveClass}>
<p>1</p>
</div>
<div onClick={this.addActiveClass}>
<p>2</p>
</div>
<div onClick={this.addActiveClass}>
<p>3</p>
</div>
</div>
}
}
javascript
reactjs
Peter Flanagan
quelle
quelle
active
jedem Element beim Klicken immer noch hinzu . Ich möchte nur, dass ein Element eine aktive Klasse hatonClick
im Gegensatz zu allen Kleinbuchstaben zu verwenden, wie Sie falsch habenIch würde es vorziehen, den "&&" -Operator für die Inline-if-Anweisung zu verwenden. Meiner Meinung nach gibt es auf diese Weise eine sauberere Codebasis.
Im Allgemeinen könnten Sie so etwas tun
render(){ return( <div> <button className={this.state.active && 'active'} onClick={ () => this.setState({active: !this.state.active}) }>Click me</button> </div> ) }
Denken Sie daran, dass die Pfeilfunktion die ES6-Funktion ist, und denken Sie daran, den Wert 'this.state.active' in class constructor () {} festzulegen
this.state = { active: false }
oder wenn Sie CSS in JSX einfügen möchten, können Sie dies auf diese Weise tun
<button style={this.state.active && style.button} >button</button>
und Sie können style json variable deklarieren
const style = { button: { background:'red' } }
Denken Sie daran, camelCase in JSX-Stylesheets zu verwenden.
quelle
Nun, Ihre addActiveClass muss wissen, was angeklickt wurde. So etwas könnte funktionieren (beachten Sie, dass ich die Informationen hinzugefügt habe, welche Divs als Statusarray aktiv sind, und dass onClick jetzt die Informationen übergibt, auf die als Parameter geklickt wurde, wonach der Status entsprechend aktualisiert wird - es gibt sicherlich intelligentere Möglichkeiten dazu mach es, aber du kommst auf die Idee).
class Test extends Component(){ constructor(props) { super(props); this.state = {activeClasses: [false, false, false]}; this.addActiveClass= this.addActiveClass.bind(this); } addActiveClass(index) { const activeClasses = [...this.state.activeClasses.slice(0, index), !this.state.activeClasses[index], this.state.activeClasses.slice(index + 1)].flat(); this.setState({activeClasses}); } render() { const activeClasses = this.state.activeClasses.slice(); return ( <div> <div className={activeClasses[0]? "active" : "inactive"} onClick={() => this.addActiveClass(0)}> <p>0</p> </div> <div className={activeClasses[1]? "active" : "inactive"} onClick={() => this.addActiveClass(1)}> <p>1</p> </div> <div onClick={() => this.addActiveClass(2)}> <p>2</p> </div> </div> ); } }
quelle
Sie können dies auch mit Haken tun .
function MyComponent (props) { const [isActive, setActive] = useState(false); const toggleClass = () => { setActive(!isActive); }; return ( <div className={isActive ? 'your_className': null} onClick={toggleClass} > <p>{props.text}</p> </div> ); }
quelle
Mit React können Sie jeder ID / jedem Element eine Umschaltklasse hinzufügen. Versuchen Sie es
style.css
.hide-text{ display: none !important; /* transition: 2s all ease-in 0.9s; */ } .left-menu-main-link{ transition: all ease-in 0.4s; } .leftbar-open{ width: 240px; min-width: 240px; /* transition: all ease-in 0.4s; */ } .leftbar-close{ width: 88px; min-width:88px; transition: all ease-in 0.4s; }
fileName.js
...... ToggleMenu=()=>{ this.setState({ isActive: !this.state.isActive }) console.log(this.state.isActive) } render() { return ( <div className={this.state.isActive===true ? "left-panel leftbar-open" : "left-panel leftbar-close"} id="leftPanel"> <div className="top-logo-container" onClick={this.ToggleMenu}> <span className={this.state.isActive===true ? "left-menu-main-link hide-from-menu" : "hide-text"}>Welcome!</span> </div> <div className="welcome-member"> <span className={this.state.isActive===true ? "left-menu-main-link hide-from-menu" : "hide-text"}>Welcome<br/>SDO Rizwan</span> </div> ) } ......
quelle
className={`left-panel ${this.state.isActive===true ? 'leftbar-open' : 'leftbar-close'}`}
React hat ein Konzept für den Komponentenstatus. Wenn Sie ihn also wechseln möchten, führen Sie Folgendes aus
setState
:constructor(props) { super(props); this.addActiveClass= this.addActiveClass.bind(this); this.state = { isActive: false } } addActiveClass() { this.setState({ isActive: true }) }
Verwenden
this.state.isActive
Sie in Ihrer Komponente , um das zu rendern, was Sie benötigen.Dies wird komplizierter, wenn Sie den Status in Komponente 1 festlegen und in Komponente 2 verwenden möchten. Erforschen Sie einfach den unidirektionalen Datenfluss und möglicherweise den Redux, der Ihnen dabei hilft, damit umzugehen.
quelle
state
aber dies erklärt immer noch nicht wirklich, wie man den Klassennamen aktualisiert, wenn auf ein Element geklickt wird<div className={this.state.isActive ? 'active' : ''}>
. Es geht um bedingtes Rendern, aber es hängt immer noch vom Zustand ab.active
Klassennamen hatItem
Komponente abstrahiert werden. Sie werden es dann dreimal einschließen und im Grunde 3 Elemente haben, von denen jedes seinen eigenenisActive
Status hat. Ist es was du meinst?Item
eine Möglichkeit, dies zu tun, ohne es in eine Komponente aufzuteilen?Die obigen Antworten funktionieren, aber falls Sie einen anderen Ansatz wünschen, versuchen Sie es mit dem Klassennamen: https://github.com/JedWatson/classnames
quelle
Eine gute Probe würde helfen, die Dinge besser zu verstehen:
HTML
<div id="root"> </div>
CSS
.box { display: block; width: 200px; height: 200px; background-color: gray; color: white; text-align: center; vertical-align: middle; cursor: pointer; } .box.green { background-color: green; }
Code reagieren
class App extends React.Component { constructor(props) { super(props); this.state = {addClass: false} } toggle() { this.setState({addClass: !this.state.addClass}); } render() { let boxClass = ["box"]; if(this.state.addClass) { boxClass.push('green'); } return( <div className={boxClass.join(' ')} onClick={this.toggle.bind(this)}>{this.state.addClass ? "Remove a class" : "Add a class (click the box)"}<br />Read the tutorial <a href="http://www.automationfuel.com" target="_blank">here</a>.</div> ); } } ReactDOM.render(<App />, document.getElementById("root"));
quelle
Sie können beim Klicken eine Umschaltklasse oder einen Umschaltstatus hinzufügen
class Test extends Component(){ state={ active:false, } toggleClass() { console.log(this.state.active) this.setState=({ active:true, }) } render() { <div> <div onClick={this.toggleClass.bind(this)}> <p>1</p> </div> </div> } }
quelle
Vielen Dank an @cssko für die richtige Antwort, aber wenn Sie es selbst versucht haben, werden Sie feststellen, dass es nicht funktioniert. Ein Vorschlag wurde von @Matei Radu gemacht, aber von @cssko abgelehnt, sodass der Code nicht ausgeführt werden kann (es wird der Fehler "Eigenschaftsbindung von undefiniert kann nicht gelesen werden" ausgegeben). Unten ist die richtige Antwort:
class MyComponent extends React.Component { constructor(props) { super(props); this.addActiveClass = this.addActiveClass.bind(this); this.state = { active: false, }; } addActiveClass() { const currentState = this.state.active; this.setState({ active: !currentState }); }; render() { return ( < div className = { this.state.active ? 'your_className' : null } onClick = { this.addActiveClass } > < p > { this.props.text } < /p> < / div > ) } } class Test extends React.Component { render() { return ( < div > < MyComponent text = { 'Clicking this will toggle the opacity through css class' } /> < / div > ); } } ReactDOM.render( < Test / > , document.body );
.your_className { opacity: 0.3 }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.12.0/umd/react-dom.production.min.js"></script>
quelle
Ich habe kürzlich angefangen, React zu lernen und wollte einen Tab erstellen, um zu sehen, wie weit mein Wissen gegangen ist. Ich bin darauf gestoßen und habe beschlossen, etwas ohne Redux zu implementieren. Ich habe das Gefühl, dass die Antworten nicht widerspiegeln, was op erreichen möchte. Er möchte nur eine aktive Komponente, aber die Antworten hier setzen alle Komponenten aktiv. Ich habe es versucht.
Unten ist eine Tab-Datei
import React, { Component } from 'react'; class Tab extends Component { render(){ const tabClassName = "col-xs-3 tab-bar"; const activeTab = this.props.activeKey === this.props.keyNumber ? "active-tab" : null; return ( <div className = {`${tabClassName} ${activeTab}`} onClick={()=>this.props.onClick(this.props.keyNumber)} > I am here </div> ); } } export default Tab;
Die Tabs-Datei ...
import React, { Component } from 'react'; import Tab from './tab'; class Tabs extends Component { constructor(props){ super(props); this.state = { currentActiveKey: 0, tabNumber: 2 }; this.setActive = this.setActive.bind(this); this.setTabNumber = this.setTabNumber.bind(this); } setTabNumber(number){ this.setState({ tabNumber: number }); } setActive (key){ this.setState({ currentActiveKey: key }); } render(){ let tabs = []; for(let i = 0; i <= this.state.tabNumber; i++){ let tab = <Tab key={i} keyNumber={i} onClick={this.setActive} activeKey={this.state.currentActiveKey}/>; tabs.push(tab); } return ( <div className="row"> {tabs} </div> ); } } export default Tabs;
Ihre Indexdatei ...
import React from 'react'; import ReactDOM from 'react-dom'; import Tabs from './components/tabs'; ReactDOM.render( <Tabs /> , document.querySelector('.container'));
und die CSS
.tab-bar { margin: 10px 10px; border: 1px solid grey; } .active-tab { border-top: 1px solid red; }
Dies ist ein Grundgerüst für etwas, das ich verbessern möchte. Wenn Sie also die tabNumber über 4 hinaus erhöhen, wird das CSS beschädigt.
quelle
Hier ist ein Code, den ich mir ausgedacht habe:
import React, {Component} from "react"; import './header.css' export default class Header extends Component{ state = { active : false }; toggleMenuSwitch = () => { this.setState((state)=>{ return{ active: !state.active } }) }; render() { //destructuring const {active} = this.state; let className = 'toggle__sidebar'; if(active){ className += ' active'; } return( <header className="header"> <div className="header__wrapper"> <div className="header__cell header__cell--logo opened"> <a href="#" className="logo"> <img src="https://www.nrgcrm.olezzek.id.lv/images/logo.svg" alt=""/> </a> <a href="#" className={className} onClick={ this.toggleMenuSwitch } data-toggle="sidebar"> <i></i> </a> </div> <div className="header__cell"> </div> </div> </header> ); }; };
quelle
React hat ein Konzept für den Komponentenstatus. Wenn Sie also umschalten möchten, verwenden Sie setState:
import React from 'react'; import TestState from './components/TestState'; class App extends React.Component { render() { return ( <div className="App"> <h1>React State Example</h1> <TestState/> </div> ); } } export default App;
import React from 'react'; class TestState extends React.Component { constructor() { super(); this.state = { message: 'Please subscribe', status: "Subscribe" } } changeMessage() { if (this.state.status === 'Subscribe') { this.setState({message : 'Thank You For Scubscribing.', status: 'Unsubscribe'}) } else { this.setState({ message: 'Please subscribe', status: 'Subscribe' }) } } render() { return ( <div> <h1>{this.state.message}</h1> <button onClick={()=> this.changeMessage() } >{this.state.status}</button> </div> ) } } export default TestState;
quelle
Ich wollte nur meinen Ansatz hinzufügen. Verwenden von Hooks und Kontextanbieter.
Nav.js
function NavBar() { const filterDispatch = useDispatchFilter() const {filter} = useStateFilter() const activeRef = useRef(null) const completeRef = useRef(null) const cancelRef = useRef(null) useEffect(() => { let activeClass = ''; let completeClass = ''; let cancelClass = ''; if(filter === ACTIVE_ORDERS){ activeClass='is-active' }else if ( filter === COMPLETE_ORDERS ){ completeClass='is-active' }else if(filter === CANCEL_ORDERS ) { cancelClass='is-active' } activeRef.current.className = activeClass completeRef.current.className = completeClass cancelRef.current.className = cancelClass }, [filter]) return ( <div className="tabs is-centered"> <ul> <li ref={activeRef}> <button className="button-base" onClick={() => filterDispatch({type: 'FILTER_ACTIVE'})} > Active </button> </li> <li ref={completeRef}> <button className="button-base" onClick={() => filterDispatch({type: 'FILTER_COMPLETE'})} > Complete </button> </li> <li ref={cancelRef}> <button className={'button-base'} onClick={() => filterDispatch({type: 'FILTER_CANCEL'})} > Cancel </button> </li> </ul> </div> ) } export default NavBar
filterContext.js
export const ACTIVE_ORDERS = [ "pending", "assigned", "pickup", "warning", "arrived", ] export const COMPLETE_ORDERS = ["complete"] export const CANCEL_ORDERS = ["cancel"] const FilterStateContext = createContext() const FilterDispatchContext = createContext() export const FilterProvider = ({ children }) => { const [state, dispatch] = useReducer(FilterReducer, { filter: ACTIVE_ORDERS }) return ( <FilterStateContext.Provider value={state}> <FilterDispatchContext.Provider value={dispatch}> {children} </FilterDispatchContext.Provider> </FilterStateContext.Provider> ) } export const useStateFilter = () => { const context = useContext(FilterStateContext) if (context === undefined) { throw new Error("place useStateMap within FilterProvider") } return context } export const useDispatchFilter = () => { const context = useContext(FilterDispatchContext) if (context === undefined) { throw new Error("place useDispatchMap within FilterProvider") } return context } export const FilterReducer = (state, action) => { switch (action.type) { case "FILTER_ACTIVE": return { ...state, filter: ACTIVE_ORDERS, } case "FILTER_COMPLETE": return { ...state, filter: COMPLETE_ORDERS, } case "FILTER_CANCEL": return { ...state, filter: CANCEL_ORDERS, } } return state }
Arbeitet schnell und ersetzt Redux.
quelle