प्रतिक्रिया - टॉगल वर्ग onclick


96

मैं यह जानने की कोशिश कर रहा हूं कि onClickसीएसएस गुणों को बदलने के लिए एक सक्रिय वर्ग को कैसे टॉगल करना है ।

मैंने कई दृष्टिकोण लिए हैं, और कई SO उत्तर पढ़े हैं। Jquery का उपयोग करना अपेक्षाकृत सरल होगा, हालांकि, मैं प्रतिक्रिया के साथ ऐसा करने का पता नहीं लगा सकता। मेरा कोड नीचे है। क्या कोई सलाह दे सकता है कि मुझे यह कैसे करना चाहिए?

प्रत्येक आइटम के लिए एक नया घटक बनाने के बिना क्या ऐसा करना संभव है?

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>
  }

}

जवाबों:


86

राज्य का उपयोग करें। प्रतिक्रियाओं डॉक्स यहाँ हैं

class MyComponent extends Component {
    constructor(props) {
        super(props);
        this.addActiveClass= this.addActiveClass.bind(this);
        this.state = {
            active: false,
        };
    }
    toggleClass() {
        const currentState = this.state.active;
        this.setState({ active: !currentState });
    };

    render() {
        return (
            <div 
                className={this.state.active ? 'your_className': null} 
                onClick={this.toggleClass} 
            >
                <p>{this.props.text}</p>
            </div>
        )
  }
}

class Test extends Component {
    render() {
        return (
            <div>
                <MyComponent text={'1'} />
                <MyComponent text={'2'} />
            </div>
        );
    }
}

3
वहाँ एक अतिरिक्त घटक बनाने के बिना ऐसा करने का एक तरीका है?
पीटर फ्लैगनन

2
आप अलग-अलग जटिल घटकों को छोटे घटकों में तोड़ना चाहते हैं। facebook.github.io/react/docs/…
cssko

1
मैंने घटक को तोड़ दिया है, लेकिन यह अभी भी activeप्रत्येक तत्व को क्लिक पर जोड़ता है। मैं केवल एक तत्व चाहता हूं कि एक सक्रिय वर्ग हो
पीटर फ्लानागन

1
इसे 'सक्रिय' वर्ग नहीं कहा जा सकता क्योंकि अन्य तत्वों की सक्रिय कक्षाएं अभी भी हैं।
डेट टीटी

6
क्या आप onClickसभी लोअरकेस के विपरीत उपयोग करने के उत्तर को अपडेट कर सकते हैं जैसा कि आपने गलत तरीके से किया है
पीटर फ्लानगन

24

अगर मैं बयान पर इनलाइन पर "&&" -ऑपरेटर का उपयोग करना पसंद करूंगा। मेरे विचार में यह इस तरह से क्लीनर कोडबेस देता है।

आम तौर पर आप ऐसा कुछ कर सकते हैं

render(){
return(
  <div>
    <button className={this.state.active && 'active'}
      onClick={ () => this.setState({active: !this.state.active}) }>Click me</button>
  </div>
)
}

बस ध्यान रखें तीर फ़ंक्शन ES6 सुविधा है और वर्ग निर्माता () {} में 'this.state.active' मान सेट करना याद रखें

this.state = { active: false }

या यदि आप JSX में css इंजेक्ट करना चाहते हैं तो आप इसे इस प्रकार कर सकते हैं

<button style={this.state.active && style.button} >button</button>

और आप शैली जसन चर घोषित कर सकते हैं

const style = { button: { background:'red' } }

JSX स्टाइलशीट पर कैमलकेस का उपयोग करना याद रखें।


2
यह घटकों पर सरल वर्गनाम को टॉगल करने का सबसे पतला तरीका है।
SeaWaryer404

12

खैर, आपके addActiveClass को यह जानने की जरूरत है कि क्या क्लिक किया गया था। कुछ इस तरह से काम कर सकता है (ध्यान दें कि मैंने वह जानकारी जोड़ी है जो divs राज्य सरणी के रूप में सक्रिय है, और यह कि onClick अब उस जानकारी को पास करता है जिसे एक पैरामीटर के रूप में क्लिक किया गया था, जिसके बाद राज्य तदनुसार अपडेट किया गया है - निश्चित रूप से होशियार तरीके हैं यह करो, लेकिन तुम विचार प्राप्त करो)।

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>
    );
  }
}

11

आप इसे हुक के साथ भी कर सकते हैं ।

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>
   );
}  

4

प्रतिक्रिया का उपयोग करके आप किसी भी आईडी / तत्व में टॉगल वर्ग जोड़ सकते हैं, कोशिश कर सकते हैं

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>
    )
    }
......

मैं इसमें यह जोड़ना चाहूंगा कि आप निम्नलिखित कोड-शैली का उपयोग कर सकते हैं यदि आपके पास एक स्थिर वर्ग है जिसे आप "isActive" कथनों में से प्रत्येक के लिए परिभाषित नहीं करना चाहते हैं:className={`left-panel ${this.state.isActive===true ? 'leftbar-open' : 'leftbar-close'}`}
Zeliax

4

प्रतिक्रिया में घटक राज्य की एक अवधारणा है, इसलिए यदि आप इसे स्विच करना चाहते हैं, तो एक करें setState:

constructor(props) {
  super(props);

  this.addActiveClass= this.addActiveClass.bind(this);
  this.state = {
    isActive: false
  }
}

addActiveClass() {
  this.setState({
    isActive: true
  })
}

अपने घटक में this.state.isActiveआप क्या जरूरत प्रस्तुत करना उपयोग करें।

जब आप घटक # 1 में स्थिति सेट करना चाहते हैं और घटक # 2 में उपयोग करना चाहते हैं तो यह अधिक जटिल हो जाता है। बस यूनिडायरेक्शनल डेटा फ्लो पर प्रतिक्रिया देने के लिए अधिक खुदाई करें और संभवत: रिडक्स करें जो आपको इसे संभालने में मदद करेंगे।


मैं समझता हूं stateलेकिन यह अभी भी नहीं समझाता है कि जब तत्व पर क्लिक किया जाता है तो
क्लासनाम

अपने jsx मार्कअप में - <div className={this.state.isActive ? 'active' : ''}>। यह सशर्त प्रतिपादन के बारे में है, लेकिन फिर भी राज्य पर निर्भर करता है।
ढोरेलिक

लेकिन वह सक्रिय आइटम को क्लिक पर प्रत्येक आइटम में जोड़ देगा। मैं सिर्फ यह चाहता हूं कि आइटम का activeनाम कक्षा के नाम पर क्लिक किया जाए
पेटनगन

2
प्रत्येक आइटम क्यों? आप जिस आइटम के लिए शर्त जोड़ते हैं, उसमें वह वर्ग जोड़ देगा। आदर्श रूप से आपके आइटम Itemघटक के लिए सारगर्भित होने चाहिए । फिर आप इसे 3 बार शामिल करेंगे और मूल रूप से 3 आइटम होंगे, प्रत्येक की अपनी isActiveस्थिति होगी। क्या आपका यही मतलब है?
ढोरेलिक

इसे एक Itemघटक में विभाजित किए बिना क्या ऐसा करने का कोई तरीका है?
पीटर फ्लानागन


2

एक अच्छा नमूना चीजों को बेहतर ढंग से समझने में मदद करेगा:

एचटीएमएल

<div id="root">
</div>

सीएसएस

.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; 
}

प्रतिक्रिया कोड

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"));

2

आप क्लिक पर टॉगल क्लास या टॉगल स्टेट जोड़ सकते हैं

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>
  }

}

2

सही उत्तर प्रदान करने के लिए @cssko को धन्यवाद, लेकिन अगर आपने इसे स्वयं आज़माया तो आपको एहसास होगा कि यह काम नहीं करता है। @Matei Radu द्वारा एक सुझाव दिया गया है, लेकिन @cssko द्वारा अस्वीकार कर दिया गया था, इसलिए कोड अप्रभावी रहता है (यह त्रुटि को फेंक देगा 'अपरिभाषित की संपत्ति को पढ़ नहीं सकता')। नीचे कार्य सही उत्तर है:

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>


1

मैंने हाल ही में रिएक्ट सीखना शुरू किया और एक टैब का निर्माण करना चाहता था ताकि यह देखा जा सके कि मेरा ज्ञान कितना दूर चला गया है। मैं इस पार आया और बिना रिडक्स के कुछ लागू करने का फैसला किया। मुझे लगता है कि उत्तर यह दर्शाता है कि ऑप क्या हासिल करना चाहता है। वह केवल एक सक्रिय घटक चाहता है लेकिन यहाँ उत्तर सभी घटकों को सक्रिय करेगा। मैंने इसे एक शॉट दिया है।

नीचे एक टैब फ़ाइल है

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;

टैब फ़ाइल ...

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;

आपकी अनुक्रमणिका फ़ाइल ...

import React from 'react';
import ReactDOM from 'react-dom';
import Tabs from './components/tabs';


ReactDOM.render(
    <Tabs />
  , document.querySelector('.container'));

और सीएसएस

.tab-bar {
    margin: 10px 10px;
    border: 1px solid grey;
}

.active-tab {
    border-top: 1px solid red;
}

यह एक चीज का कंकाल है जिसे मैं सुधारना चाहता हूं ताकि टैबनंबर में वृद्धि 4 से परे सीएसएस टूट जाएगी।


1

यहाँ एक कोड है जो मैं ऊपर आया था:

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>
        );
    };
};

1

रिएक्ट में घटकों की स्थिति की अवधारणा है, इसलिए यदि आप टॉगल करना चाहते हैं, तो setState का उपयोग करें:

  1. App.js
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;
  1. घटकों / TestState.js
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;
  1. उत्पादन

यहां छवि विवरण दर्ज करें


0

बस मेरा दृष्टिकोण जोड़ना चाहता था। हुक और संदर्भ प्रदाता का उपयोग करना।

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
}

तेजी से काम करता है, और जगह बदल देता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.