Saya mencoba mencari cara untuk mengaktifkan kelas aktif onClick
untuk mengubah properti CSS.
Saya telah mengambil banyak pendekatan, dan membaca banyak jawaban SO. Menggunakan jquery itu akan relatif sederhana, namun, saya tidak tahu melakukan ini dengan react. Kode saya ada di bawah. Adakah yang bisa memberi tahu bagaimana saya harus melakukan ini?
Tanpa membuat komponen baru untuk setiap item, apakah mungkin melakukan ini?
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
sumber
sumber
active
setiap elemen saat diklik. Saya hanya ingin satu elemen memiliki kelas yang aktifonClick
sebagai lawan dari semua huruf kecil karena Anda salahSaya lebih suka menggunakan "&&" -operator pada pernyataan-if sebaris. Menurut pendapat saya, cara ini memberikan basis kode yang lebih bersih.
Biasanya Anda bisa melakukan hal seperti ini
render(){ return( <div> <button className={this.state.active && 'active'} onClick={ () => this.setState({active: !this.state.active}) }>Click me</button> </div> ) }
Ingatlah bahwa fungsi panah adalah fitur ES6 dan ingat untuk menyetel nilai 'this.state.active' di class constructor () {}
this.state = { active: false }
atau jika Anda ingin menginjeksi css di JSX, Anda bisa melakukannya dengan cara ini
<button style={this.state.active && style.button} >button</button>
dan Anda dapat mendeklarasikan variabel style json
const style = { button: { background:'red' } }
ingat menggunakan camelCase di stylesheet JSX.
sumber
Nah, addActiveClass Anda perlu tahu apa yang diklik. Sesuatu seperti ini dapat berfungsi (perhatikan bahwa saya telah menambahkan informasi div mana yang aktif sebagai larik status, dan bahwa onClick sekarang meneruskan informasi apa yang diklik sebagai parameter setelah status diperbarui dengan semestinya - tentu ada cara yang lebih cerdas untuk lakukan, tetapi Anda mendapatkan idenya).
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> ); } }
sumber
Anda juga bisa melakukan ini dengan pengait .
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> ); }
sumber
menggunakan React Anda dapat menambahkan kelas toggle ke id / elemen apapun, coba
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> ) } ......
sumber
className={`left-panel ${this.state.isActive===true ? 'leftbar-open' : 'leftbar-close'}`}
React memiliki konsep status komponen, jadi jika Anda ingin mengubahnya, lakukan
setState
:constructor(props) { super(props); this.addActiveClass= this.addActiveClass.bind(this); this.state = { isActive: false } } addActiveClass() { this.setState({ isActive: true }) }
Dalam komponen Anda gunakan
this.state.isActive
untuk membuat apa yang Anda butuhkan.Ini menjadi lebih rumit ketika Anda ingin menyetel status di komponen # 1 dan menggunakannya di komponen # 2. Gali lebih banyak lagi untuk bereaksi aliran data searah dan mungkin reduksi yang akan membantu Anda menanganinya.
sumber
state
tetapi ini masih belum benar-benar menjelaskan cara memperbarui nama kelas ketika sebuah elemen diklik<div className={this.state.isActive ? 'active' : ''}>
. Ini tentang rendering bersyarat, tetapi masih bergantung pada status.active
nama kelasItem
komponen. Anda kemudian akan memasukkannya 3 kali dan pada dasarnya akan memiliki 3 item, masing-masing memiliki statusnya sendiriisActive
. Apa yang kamu maksudItem
komponen, apakah ada cara untuk melakukan ini?Jawaban di atas akan berfungsi, tetapi jika Anda menginginkan pendekatan yang berbeda, coba nama kelas: https://github.com/JedWatson/classnames
sumber
Sampel yang baik akan membantu memahami berbagai hal dengan lebih baik:
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; }
Kode React
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"));
sumber
Anda dapat menambahkan kelas sakelar atau status sakelar saat diklik
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> } }
sumber
Terima kasih kepada @cssko untuk memberikan jawaban yang benar, tetapi jika Anda mencobanya sendiri, Anda akan menyadari bahwa itu tidak berhasil. Sebuah saran telah dibuat oleh @Matei Radu, tetapi ditolak oleh @cssko, sehingga kode tetap tidak dapat dijelajahi (ini akan memunculkan kesalahan 'Tidak dapat membaca ikatan properti tidak terdefinisi'). Di bawah ini adalah jawaban yang benar:
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>
sumber
Saya mulai belajar React baru-baru ini dan ingin membuat tab hanya untuk melihat sejauh mana pengetahuan saya telah berkembang. Saya menemukan ini dan memutuskan untuk menerapkan sesuatu tanpa redux. Saya merasa jawabannya tidak mencerminkan apa yang ingin dicapai oleh operasi. Dia ingin hanya satu komponen aktif tetapi jawaban di sini akan membuat semua komponen aktif. Saya telah mencobanya.
Di bawah ini adalah file tab
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;
File tab ...
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;
file indeks Anda ...
import React from 'react'; import ReactDOM from 'react-dom'; import Tabs from './components/tabs'; ReactDOM.render( <Tabs /> , document.querySelector('.container'));
dan css
.tab-bar { margin: 10px 10px; border: 1px solid grey; } .active-tab { border-top: 1px solid red; }
Ini adalah kerangka dari sesuatu yang ingin saya tingkatkan sehingga meningkatkan tabNumber melebihi 4 akan merusak css.
sumber
Ini adalah kode yang saya buat:
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> ); }; };
sumber
React memiliki konsep status komponen, jadi jika Anda ingin beralih, gunakan 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;
sumber
Hanya ingin menambahkan pendekatan saya. Menggunakan hook dan penyedia konteks.
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 }
Bekerja cepat, dan menggantikan redux.
sumber