एक घटक ReactJS में नियंत्रित त्रुटि के लिए टाइप टेक्स्ट के अनियंत्रित इनपुट को बदल रहा है


331

चेतावनी: एक घटक को नियंत्रित करने के लिए टाइप टेक्स्ट का अनियंत्रित इनपुट बदल रहा है। इनपुट तत्वों को अनियंत्रित से नियंत्रित (या इसके विपरीत) स्विच नहीं करना चाहिए। घटक के जीवनकाल के लिए नियंत्रित या अनियंत्रित इनपुट तत्व का उपयोग करने के बीच का निर्णय लें। *

निम्नलिखित मेरा कोड है:

constructor(props) {
  super(props);
  this.state = {
    fields: {},
    errors: {}
  }
  this.onSubmit = this.onSubmit.bind(this);
}

....

onChange(field, e){
  let fields = this.state.fields;
  fields[field] = e.target.value;
  this.setState({fields});
}

....

render() {
  return(
    <div className="form-group">
      <input
        value={this.state.fields["name"]}
        onChange={this.onChange.bind(this, "name")}
        className="form-control"
        type="text"
        refs="name"
        placeholder="Name *"
      />
      <span style={{color: "red"}}>{this.state.errors["name"]}</span>
    </div>
  )
}

1
fieldsराज्य का प्रारंभिक मूल्य क्या है ?
मयंक शुक्ला

2
कंस्ट्रक्टर (प्रॉप्स) {सुपर (प्रॉप्स); this.state = {फ़ील्ड: {}, त्रुटियां: {}} this.onSubmit = this.onSubmit.bind (यह); }
रिया कपूरिया

जवाबों:


650

कारण यह है कि, आपके द्वारा परिभाषित राज्य में:

this.state = { fields: {} }

फ़ील्ड एक रिक्त वस्तु के रूप में, इसलिए पहले रेंडरिंग के दौरान this.state.fields.nameहोगी undefined, और इनपुट फ़ील्ड को इसका मान मिलेगा:

value={undefined}

उसके कारण, इनपुट फ़ील्ड अनियंत्रित हो जाएगी।

एक बार जब आप इनपुट में कोई भी मूल्य दर्ज करते हैं, तो fieldsराज्य में बदल जाता है:

this.state = { fields: {name: 'xyz'} }

और उस समय इनपुट क्षेत्र एक नियंत्रित घटक में परिवर्तित हो जाता है; इसलिए आपको त्रुटि मिल रही है:

एक घटक नियंत्रित करने के लिए टाइप टेक्स्ट के अनियंत्रित इनपुट को बदल रहा है।

संभव समाधान:

1- fieldsराज्य में परिभाषित करें :

this.state = { fields: {name: ''} }

2- या इस तरह शॉर्ट-सर्किट मूल्यांकन का उपयोग करके मूल्य संपत्ति को परिभाषित करें:

value={this.state.fields.name || ''}   // (undefined || '') = ''

4
क्या कोई कारण अपरिभाषित "अनियंत्रित" है जबकि बाद वाला "नियंत्रित" है - इसका क्या मतलब है?
प्रशान्त सुब्रमण्यन

@PrashanthSubramanian शायद इससे इसे बेहतर तरीके से समझने में मदद मिल सके। reactjs.org/docs/forms.html#controlled-compenders
rotimi-best

2
क्योंकि ''एक मान्य स्ट्रिंग मान है। इसलिए जब आप '''xyz' में बदलते हैं, तो इनपुट प्रकार परिवर्तित नहीं होता है जिसका अर्थ नियंत्रित करने के लिए नियंत्रित होता है। लेकिन के मामले में undefinedकरने के लिए xyzप्रकार अनियंत्रित से नियंत्रित करने के लिए बदल जाएगा।
मयंक शुक्ला

1
शुक्रिया यह मेरे लिए काम किया:value={this.state.fields.name || ''}
बॉब

1
गजब का! क्योंकि मैंने आधिकारिक डॉक्स में इसका उल्लेख नहीं किया है, या मैं अंधा हूं? स्रोत से लिंक कृपया :)
धीरज

34

इसे बदलने valueका defaultValueसंकल्प लिया जाएगा।

नोट :

defaultValueकेवल प्रारंभिक भार के लिए है। यदि आप को प्रारंभ करना चाहते हैं inputतो आपको उपयोग करना चाहिए defaultValue, लेकिन यदि आप stateमूल्य को बदलने के लिए उपयोग करना चाहते हैं तो आपको उपयोग करने की आवश्यकता है value। पढ़ें यह अधिक के लिए।

मैं प्रयोग किया जाता value={this.state.input ||""}में inputउस चेतावनी से छुटकारा पाने के।


2
धन्यवाद! मुझे इस समस्या के बारे में पता चला और अन्य समाधान मुझ पर लागू नहीं हुए, लेकिन इस समाधान से मदद मिली।
पेपरपरेड

14

घटक के अंदर इनपुट बॉक्स को निम्नलिखित तरीके से रखा गया है।

<input className="class-name"
              type= "text"
              id="id-123"
              value={ this.state.value || "" }
              name="field-name"
              placeholder="Enter Name"
              />

13

SIMPLY, आपको पहले प्रारंभिक राज्य सेट करना होगा

यदि आप प्रारंभिक स्थिति निर्धारित नहीं करते हैं तो प्रतिक्रिया एक अनियंत्रित घटक के रूप में व्यवहार करेगी


10

स्वीकृत उत्तर के अतिरिक्त, यदि आप एक inputप्रकार का उपयोग कर रहे हैं checkboxया radio, मैंने पाया है कि मुझे checkedविशेषता के रूप में अच्छी तरह से जांचने की आवश्यकता नहीं है ।

<input
  id={myId}
  name={myName}
  type="checkbox" // or "radio"
  value={myStateValue || ''}
  checked={someBoolean ? someBoolean : false}
  />

और यदि आप टीएस (या बैबेल) का उपयोग कर रहे हैं, तो आप तार्किक या ऑपरेटर के बजाय nullish coalescing का उपयोग कर सकते हैं:

value={myStateValue ?? ''}
checked={someBoolean ?? false}

8

पहले वर्तमान स्थिति सेट करें ...this.state

इसका कारण यह है कि जब आप एक नया राज्य सौंपने जा रहे हों तो यह अपरिभाषित हो सकता है। इसलिए यह वर्तमान राज्य को निकालने वाले राज्य को भी निर्धारित करके तय किया जाएगा

this.setState({...this.state, field})

यदि आपके राज्य में कोई ऑब्जेक्ट है, तो आपको निम्नानुसार राज्य सेट करना चाहिए, मान लें कि आपको उपयोगकर्ता ऑब्जेक्ट के अंदर उपयोगकर्ता नाम सेट करना है।

this.setState({user:{...this.state.user, ['username']: username}})

1
जहां तक ​​मैं इसे समझता हूं, सेटस्टैट पहले से ही केवल खेतों को ओवरराइड करता है, इसलिए पहले मामले में यह विनाशकारी कार्य के लिए अनावश्यक होना चाहिए। दूसरे राज्य में यह आवश्यक हो सकता है क्योंकि सेटस्टेट एक उप-वस्तु थोक की जगह लेगा।
क्ज़िकई

6
const [name, setName] = useState()

जैसे ही आप पाठ क्षेत्र में टाइप करते हैं, त्रुटि उत्पन्न करता है

const [name, setName] = useState('') // <-- by putting in quotes 

इस स्ट्रिंग उदाहरण पर समस्या को ठीक करेगा।


2

यदि आप फ़ील्ड में कई इनपुट का उपयोग करते हैं, तो निम्न करें: उदाहरण के लिए:

class AddUser extends React.Component {
   constructor(props){
     super(props);

     this.state = {
       fields: { UserName: '', Password: '' }
     };
   }

   onChangeField = event => {
    let name = event.target.name;
    let value = event.target.value;
    this.setState(prevState => {
        prevState.fields[name] =  value;
        return {
           fields: prevState.fields
        };
    });
  };

  render() { 
     const { UserName, Password } = this.state.fields;
     return (
         <form>
             <div>
                 <label htmlFor="UserName">UserName</label>
                 <input type="text" 
                        id='UserName' 
                        name='UserName'
                        value={UserName}
                        onChange={this.onChangeField}/>
              </div>
              <div>
                  <label htmlFor="Password">Password</label>
                  <input type="password" 
                         id='Password' 
                         name='Password'
                         value={Password}
                         onChange={this.onChangeField}/>
              </div>
         </form>
     ); 
  }
}

पर अपनी समस्या खोजें:

onChangeField = event => {
    let name = event.target.name;
    let value = event.target.value;
    this.setState(prevState => {
        prevState.fields[name] =  value;
        return {
            fields: prevState.fields
        };
    });
};

1

रिएक्ट हुक का उपयोग करना भी प्रारंभिक मूल्य निर्धारित करने के लिए मत भूलना।
मैं उपयोग कर रहा था <input type='datetime-local' value={eventStart} />और प्रारंभिक eventStartजैसा था

const [eventStart, setEventStart] = useState();
इसके बजाय
const [eventStart, setEventStart] = useState('');

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

यह इस विषय में मेरा छोटा सा योगदान है, शायद यह किसी की मदद करेगा।


0

मेरे मामले में, मयंक शुक्ला का शीर्ष उत्तर यही कहता है। एकमात्र विवरण यह था कि मेरे राज्य में मेरे द्वारा परिभाषित संपत्ति की पूरी तरह से कमी थी।

उदाहरण के लिए, यदि आपके पास यह स्थिति है:

state = {
    "a" : "A",
    "b" : "B",
}

यदि आप अपने कोड का विस्तार कर रहे हैं, तो आप एक नया प्रोप जोड़ना चाह सकते हैं, कहीं और आपके कोड में आप एक नई प्रॉपर्टी बना सकते हैं, cजिसका मान न केवल घटक की स्थिति पर अपरिभाषित है, बल्कि संपत्ति स्वयं अपरिभाषित है।

इसे हल करने के लिए बस cअपने राज्य में जोड़ना सुनिश्चित करें और इसे उचित प्रारंभिक मूल्य दें।

जैसे,

state = {
    "a" : "A",
    "b" : "B",
    "c" : "C", // added and initialized property!
}

आशा है कि मैं अपने किनारे के मामले की व्याख्या करने में सक्षम था।


0

मुझे एक ही चेतावनी मिल रही है: एक घटक नियंत्रित होने के लिए छिपे हुए प्रकार के अनियंत्रित इनपुट को बदल रहा है। मैं अपनी समस्या ठीक नहीं कर सकता। कोई विचार क्यों?

export default ({  valueName, onChangeAllg,}) => {

          <TextField
            id={"name"}
            select
            label={"name"}
            value={valueName.geschlecht || ""}
            name={"name"}
            onChange={onChangeAllg}

          >
            {nameList.map((option) => (
              <MenuItem key={option.value} value={option.value}>
                {option.label}
              </MenuItem>
            ))}
          </TextField>

मैंने कोशिश की ({ valueName, valueName: {geschlecht=""}, onChangeAllg,})औरvalue={valueName.geschlecht || ""}


मुझे यह मिला। एक defaultValue={""}TextField के अंदर याद आ रही थी
डॉ Malte Westerloh

0

चेतावनी: एक घटक को नियंत्रित करने के लिए टाइप टेक्स्ट का अनियंत्रित इनपुट बदल रहा है। इनपुट तत्वों को अनियंत्रित से नियंत्रित (या इसके विपरीत) स्विच नहीं करना चाहिए। घटक के जीवनकाल के लिए नियंत्रित या अनियंत्रित इनपुट तत्व का उपयोग करने के बीच का निर्णय लें।

समाधान: जाँच करें कि क्या मान अपरिभाषित नहीं है

प्रतिक्रिया / फॉर्मिक / बूटस्ट्रैप / टाइपस्क्रिप्ट

उदाहरण :

{ values?.purchaseObligation.remainingYear ?
  <Input
   tag={Field}
   name="purchaseObligation.remainingYear"
   type="text"
   component="input"
  /> : null
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.