प्रतिक्रिया घटक का बूलियन राज्य कैसे टॉगल करें?


86

मैं जानना चाहता हूं कि प्रतिक्रिया घटक के बूलियन राज्य को कैसे टॉगल करना है। उदाहरण के लिए:

मेरे कंपोनेंट के कंस्ट्रक्टर में बूलियन स्टेट चेक है:

constructor(props, context) { 
   super(props, context);

   this.state = {
      check: false
   };
};

मैं हर बार मेरे चेकबॉक्स को क्लिक करने की स्थिति में टॉगल करने की कोशिश कर रहा हूं, इस .setState पद्धति का उपयोग करके:

<label><input type=checkbox" value="check" onChange = {(e) => this.setState({check: !check.value})}/> Checkbox </label>

बेशक मुझे एक अनक्रेडेड संदर्भ दिया गया है: चेक परिभाषित नहीं है । तो मैं इसे कैसे प्राप्त कर सकता हूं?

अग्रिम में बहुत धन्यवाद।


3
यह बिल्कुल वैसा ही है जैसा यह कहता है, चेक अपरिभाषित है। आप शायद अंदर लिखने के लिए this.state.checkथे this.setState({check: !check.value})। और चेकबॉक्स के लिए जाँच की गई संपत्ति जोड़ें, जो घटक स्थिति के अनुसार बदल जाएगी। checked={this.state.checked}
विंकस स्टोनिस

जवाबों:


247

चूंकि किसी ने इसे पोस्ट नहीं किया है, मैं सही उत्तर पोस्ट कर रहा हूं। यदि आपका नया राज्य अपडेट पिछली स्थिति पर निर्भर करता है, तो हमेशा कार्यात्मक रूप का उपयोग करें, setStateजो एक तर्क के रूप में स्वीकार करता है जो एक नया राज्य लौटाता है।

आपके मामले में:

this.setState(prevState => ({
  check: !prevState.check
}));

डॉक्स देखें


चूंकि यह उत्तर लोकप्रिय हो रहा है, इस दृष्टिकोण को जोड़ने के लिए जो रिएक्ट हुक के लिए इस्तेमाल किया जाना चाहिए (v16.8 +) -

यदि आप useStateहुक का उपयोग कर रहे हैं , तो निम्नलिखित कोड का उपयोग करें (यदि आपका नया राज्य पिछली स्थिति पर निर्भर करता है):

const [check, setCheck] = useState(false);
// ...
setCheck(prevCheck => prevCheck + 1);

4
यह सीधे उपयोग करने से बेहतर क्यों है this.setState({check: !this.state.check})?
सनीप्रो

10
@SunnyPro लिंक किए गए डॉक्स पढ़ें और आपको अपना उत्तर मिल जाएगा। टीएल; डीआर प्रतिक्रिया है कि कॉल को एक साथ बैच कर राज्य सेट करने के लिए अनुकूलन करता है। तो एक साधारण वेतन वृद्धि फ़ंक्शन increment = () => this.setState({count: this.state.count + 1});और कोड के एक ब्लॉक की कल्पना increment(); increment(); increment();करें : अब प्रतिक्रिया इनको किसी चीज़ के अनुरूप कर सकती है: setNewState = (oldState) => { newState.count = oldState.count + 1; newState.count = oldState.count + 1; newState.count = oldState.count + 1; return newState; } देखें कि समस्या कहाँ है?
ड्रयू रीज़

क्या होगा यदि मुझे अन्य राज्य संपत्तियों को अपडेट करने की आवश्यकता है जो पिछले राज्य पर निर्भर नहीं हैं? उदाहरण के लिए, एक पॉपओवर संदेश को टॉगल करना, जो कि सत्य / असत्य के रूप में दिखाई देता है, लेकिन संदेश राज्य पर निर्भर करता है?
हैमन्चेज़

1
@hamncheez फ़ंक्शन की वापसी मान वैसे भी आपकी नई स्थिति है। आप पिछली स्थिति के मूल्यों का उपयोग कर सकते हैं या नहीं कर सकते हैं; इसलिए आप विभिन्न संदेशों की तरह, किसी भी मान में भेज सकते हैं।
डेन

17

आपको यहां के this.state.checkबजाय उपयोग करना चाहिए check.value:

this.setState({check: !this.state.check})

लेकिन वैसे भी इसे इस तरह से करना बुरा है । इसे अलग तरीके से स्थानांतरित करने के लिए बेहतर है और मार्कअप में सीधे कॉलबैक न लिखें।


अपवादात्मक, लेकिन जिज्ञासा से बाहर - यह "बुरा अभ्यास" क्यों है?
फेलो स्ट्रेंजर

व्यू और लॉजिक को अलग करना बेहतर है क्योंकि इस तरह से आप अपने लॉजिक और मार्कअप को अलग-अलग और आसानी से देख और अपडेट कर पाएंगे।
यूजीन त्सख

2
यह केवल बुरा अभ्यास नहीं है, लेकिन आपको वांछित परिणाम नहीं मिल सकता है, जैसा setStateकि async है । नीचे मेरा जवाब देखें।
डेन

1
मुझे लगता है कि डेन के जवाब में एक बेहतर दृष्टिकोण है क्योंकि यह प्रतिक्रिया की एपीआई का उपयोग करता है जिसका उपयोग नए राज्य की पिछली स्थिति पर निर्भर करता है।
एमटी।

3
@MT। लेकिन फिर, मैंने सालों बाद जवाब दिया। वहाँ है कि :)
डेन

5

checkedमान प्राप्त करने के लिए उपयोग करें । के दौरान onChange, checkedहोगा trueऔर यह एक प्रकार का होगाboolean

उम्मीद है की यह मदद करेगा!

class A extends React.Component {
  constructor() {
    super()
    this.handleCheckBox = this.handleCheckBox.bind(this)
    this.state = {
      checked: false
    }
  }
  
  handleCheckBox(e) {
    this.setState({
      checked: e.target.checked
    })
  }
  
  render(){
    return <input type="checkbox" onChange={this.handleCheckBox} checked={this.state.checked} />
  }
}

ReactDOM.render(<A/>, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>


4

यहां हुक का उपयोग करके एक उदाहरण दिया गया है (प्रतिक्रिया की आवश्यकता है = = 16.8.0)

// import React, { useState } from 'react';
const { useState } = React;

function App() {
  const [checked, setChecked] = useState(false);
  const toggleChecked = () => setChecked(value => !value);
  return (
    <input
      type="checkbox"
      checked={checked}
      onChange={toggleChecked}
    />
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

<div id="root"><div>


3

आप useStateफ़ंक्शन घटक के लिए स्थानीय स्थिति घोषित करने के लिए रिएक्ट के हुक का उपयोग भी कर सकते हैं । चर की प्रारंभिक स्थिति toggledको विधि के तर्क के रूप में पारित किया गया है .useState

import { render } from 'react-dom';
import React from "react";

type Props = {
  text: string,
  onClick(event: React.MouseEvent<HTMLButtonElement>): void,
};

export function HelloWorldButton(props: Props) {
  const [toggled, setToggled] = React.useState(false); // returns a stateful value, and a function to update it
  return <button
  onClick={(event) => {
    setToggled(!toggled);
    props.onClick(event);
  }}
  >{props.text} (toggled: {toggled.toString()})</button>;
}


render(<HelloWorldButton text='Hello World' onClick={() => console.log('clicked!')} />, document.getElementById('root'));

https://stackblitz.com/edit/react-ts-qga3vc


2

प्रयत्न:

<label><input type=checkbox" value="check" onChange = {(e) => this.setState({check: !this.state.check.value})}/> Checkbox </label>

check: !check.valueइसका उपयोग करते हुए इसका मतलब हैcheck वस्तु की है, जिसे आपने घोषित नहीं किया है।

आपको यह निर्दिष्ट करने की आवश्यकता है कि आप इसके विपरीत मूल्य चाहते हैं this.state.check


2

मुझे यह सबसे सरल लगा जब बूलियन मूल्यों को टॉगल करना। सीधे शब्दों में कहें यदि मूल्य पहले से ही सत्य है तो यह इसे गलत और इसके विपरीत निर्धारित करता है। अपरिभाषित त्रुटियों से सावधान रहें, सुनिश्चित करें कि निष्पादित करने से पहले आपकी संपत्ति परिभाषित की गई थी

this.setState({
   propertyName: this.propertyName = !this.propertyName
});

! इसके लिए धन्यवाद। इसने मेरे लिए काम किया।
मो

2

आपके संदर्भ के आधार पर; यह आपको स्टेट को दिए गए माउसइंटर फ़ंक्शन को अपडेट करने की अनुमति देगा। किसी भी तरह से, राज्य के मान को या तो सही पर सेट करके: असत्य आप अद्यतन कर सकते हैं कि राज्य मान किसी भी फ़ंक्शन को विरोध मूल्य के साथ सेट करके दिया गया है!this.state.variable

state = {
  hover: false
}

onMouseEnter = () => {
  this.setState({
    hover: !this.state.hover
  });
};

0

जब मैं Redux का उपयोग करके रिएक्ट घटक में टॉगल स्टेट का उपयोग करने के लिए खोज कर रहा हूं, तो मुझे इस पृष्ठ पर उतारा गया था, लेकिन मैं यहां किसी भी दृष्टिकोण का उपयोग नहीं कर रहा हूं।

इसलिए, मुझे लगता है कि यह किसी ऐसे व्यक्ति की मदद कर सकता है जो Redux का उपयोग करके टॉगल राज्य को लागू करने के लिए संघर्ष कर रहा था।

मेरी reducer फ़ाइल यहाँ जाती है। मुझे प्रारंभिक अवस्था डिफ़ॉल्ट रूप से गलत लगती है।

const INITIAL_STATE = { popup: false };
export default (state = INITIAL_STATE, action) => {
    switch (action.type) {
        case "POPUP":
            return {
                ...state,
                popup: action.value
            };
        default:
            return state;
    }
    return state;
};

मैं छवि को क्लिक करने पर स्थिति बदलता हूं। तो, मेरा img टैग यहाँ पर onClick फ़ंक्शन के साथ जाता है।

<img onClick={togglePopup} src={props.currentUser.image} className="avatar-image avatar-image--icon" />

मेरा टॉगल पॉपअप फ़ंक्शन नीचे जाता है, जिसे डिस्पैचर कहते हैं।

const togglePopup = ev => {
    ev.preventDefault();
    props.handlePopup(!props.popup);
};

यह कॉल नीचे दिए गए mapDispatchToProps फ़ंक्शन के लिए जाता है जो वापस टॉगल अवस्था को दर्शाता है।

const mapDispatchToProps = dispatch => ({
    handlePopup: value => dispatch({ type: "POPUP", value })
});

धन्यवाद।

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