প্রতিক্রিয়া - একটি অনিয়ন্ত্রিত ইনপুট পরিবর্তন করা


359

আমার কাছে একটি ফর্মের সাথে একটি সাধারণ প্রতিক্রিয়া উপাদান রয়েছে যা আমি বিশ্বাস করি যে এটির একটি নিয়ন্ত্রিত ইনপুট রয়েছে:

import React from 'react';

export default class MyForm extends React.Component {
    constructor(props) {
        super(props);
        this.state = {}
    }

    render() {
        return (
            <form className="add-support-staff-form">
                <input name="name" type="text" value={this.state.name} onChange={this.onFieldChange('name').bind(this)}/>
            </form>
        )
    }

    onFieldChange(fieldName) {
        return function (event) {
            this.setState({[fieldName]: event.target.value});
        }
    }
}

export default MyForm;

আমি আমার অ্যাপ্লিকেশনটি চালানোর সময় আমি নিম্নলিখিত সতর্কতাটি পাই:

সতর্কতা: মাইফোর্ম নিয়ন্ত্রণ করতে টাইপ পাঠ্যের একটি অনিয়ন্ত্রিত ইনপুট পরিবর্তন করছে। ইনপুট উপাদানগুলি নিয়ন্ত্রণহীন (বা বিপরীতে) অনিয়ন্ত্রিত থেকে স্যুইচ করা উচিত নয়। উপাদানটির আজীবন নিয়ন্ত্রিত বা অনিয়ন্ত্রিত ইনপুট উপাদানটি ব্যবহার করার মধ্যে সিদ্ধান্ত নিন

আমি বিশ্বাস করি যে আমার ইনপুটটির একটি মান রয়েছে তাই এটি নিয়ন্ত্রণ করা হয়। আমি ভাবছি আমি কী ভুল করছি?

আমি 15.1.0 প্রতিক্রিয়া ব্যবহার করছি

উত্তর:


509

আমি বিশ্বাস করি যে আমার ইনপুটটির একটি মান রয়েছে তাই এটি নিয়ন্ত্রণ করা হয়।

কোনও ইনপুট নিয়ন্ত্রিত হওয়ার জন্য, এর মানটি অবশ্যই একটি রাষ্ট্রের পরিবর্তনশীলের সাথে সমান।

শর্তটি প্রাথমিকভাবে আপনার উদাহরণটিতে পূরণ this.state.nameকরা হয়নি কারণ প্রাথমিকভাবে সেট করা হয়নি। সুতরাং, ইনপুটটি প্রাথমিকভাবে নিয়ন্ত্রণহীন। onChangeহ্যান্ডলারটি প্রথমবারের জন্য ট্রিগার হয়ে গেলে this.state.nameসেট হয়ে যায়। সেই সময়ে, উপরের শর্তটি সন্তুষ্ট এবং ইনপুটটিকে নিয়ন্ত্রিত বলে মনে করা হয়। নিয়ন্ত্রিত থেকে নিয়ন্ত্রিত হয়ে এই রূপান্তরটি উপরে দেখা ত্রুটি তৈরি করে।

আরম্ভের দ্বারা this.state.nameকন্সট্রাকটর মধ্যে:

যেমন

this.state = { name: '' };

সমস্যাটি ঠিক করে ইনপুটটি শুরু থেকেই নিয়ন্ত্রণ করা হবে। আরও উদাহরণের জন্য নিয়ন্ত্রিত উপাদানগুলি প্রতিক্রিয়া দেখুন ।

এই ত্রুটির সাথে সম্পর্কিত নয়, আপনার কেবলমাত্র একটি ডিফল্ট রফতানি হওয়া উচিত। আপনার কোড দুটিতে আছে।


7
উত্তরটি পড়া এবং ধারণাটি অনেকবার অনুসরণ করা কঠিন তবে এই উত্তরটি গল্পটি বলার এবং দর্শকদের একই সাথে বোঝার সঠিক উপায়। উত্তর স্তরের godশ্বর!
সুরজনউ 55

2
আপনার যদি লুপে গতিশীল ক্ষেত্র থাকে? যেমন আপনি ক্ষেত্রের নামটি সেট করেছেন name={'question_groups.${questionItem.id}'}?
ব্যবহারকারী 3574492

2
গতিশীল ক্ষেত্রগুলি কীভাবে কাজ করবে। ডায়নামিকভাবে ফর্মটি জেনারেট করছি এবং তারপরে ফিল্ডের নামগুলি কোনও স্টেটের অভ্যন্তরে অবস্থিত স্থানে সেট করে দিচ্ছি, আমাকে কি এখনও প্রথমে ম্যানুয়ালি প্রথমে রাজ্যে নামগুলি সেট করতে হবে এবং তারপরে সেগুলি আমার অবজেক্টে স্থানান্তর করতে হবে?
জোসেফ

13
এই উত্তরটি কিছুটা ভুল। প্রোপটির নন-নাল / অপরিজ্ঞাত মান থাকলেvalue কোনও ইনপুট নিয়ন্ত্রণ করা হয়। প্রোপটির কোনও রাষ্ট্রীয় পরিবর্তনশীলের সাথে মিল থাকার দরকার নেই (এটি কেবল একটি ধ্রুবক হতে পারে এবং উপাদানটি এখনও নিয়ন্ত্রিত হিসাবে বিবেচিত হবে)। আদমের উত্তর আরও সঠিক এবং গ্রহণ করা উচিত।
ecraig12345

2
হ্যাঁ - এটি প্রযুক্তিগতভাবে ভুল উত্তর (তবে সহায়ক)। এ সম্পর্কে একটি নোট - আপনি যদি রেডিও বোতামগুলির সাথে ডিল করছেন (যার 'মান' কিছুটা আলাদাভাবে নিয়ন্ত্রিত হয়) তবে এই প্রতিক্রিয়া সতর্কতাটি আসলে আপনার উপাদানটি নিয়ন্ত্রণ করা থাকলেও (বর্তমানে) নিক্ষেপ করতে পারে। github.com/facebook/react/issues/6779 , এবং একটি যুক্ত করে স্থির করা যায় !! সত্য যাচাই করা হয়েছে
মায়াভাররা

122

আপনি যখন প্রথম নিজের উপাদানটি রেন্ডার করেন, this.state.nameসেট করা থাকে না, তাই এটি মূল্যায়ন করে undefinedবা nullআপনার এবং আপনি শেষ value={undefined}বা value={null}আপনার কাছে চলে যান input

যখন রিঅ্যাক্টডোম কোনও ক্ষেত্রটি নিয়ন্ত্রিত হয়েছে কিনা তা পরীক্ষা করে দেখুনvalue != null , এটি পরীক্ষা করে দেখুন (নোট করুন যে এটি !=, না !==) এবং যেহেতু undefined == nullজাভাস্ক্রিপ্টে, এটি সিদ্ধান্ত নেয় যে এটি অনিয়ন্ত্রিত।

সুতরাং, যখন onFieldChange()ডাকা হয়, this.state.nameএকটি স্ট্রিং মান হিসাবে সেট করা হয়, আপনার ইনপুট নিয়ন্ত্রণ থেকে নিয়ন্ত্রণ থেকে নিয়ন্ত্রণ থেকে যায়।

যদি আপনি না this.state = {name: ''}আপনার কন্সট্রাকটর মধ্যে, কারণ '' != null, আপনার ইনপুট একটি মান পুরো সময় থাকবে এবং সেই বার্তার চলে যাবে।


5
এটি মূল্যবান জন্য, একই জিনিসটি ঘটতে পারে this.props.<whatever>, যা আমার শেষদিকে সমস্যা ছিল। ধন্যবাদ, আদম!
ডন

হাঁ! আপনি যদি render()নির্ধারিত কোনও গণনাযুক্ত ভেরিয়েবল পাস করেন বা ট্যাগ নিজেই একটি অভিব্যক্তি pass যা যা মূল্যায়ন করে তাও পাস হতে পারে undefined। আমি সাহায্য করতে পেরে আনন্দিত!
লেহে ব্রেনেক্কি

1
এই উত্তরের জন্য ধন্যবাদ: যদিও এটি স্বীকৃত উত্তর না হলেও এটি "" একটি নির্দিষ্ট করুন "এর চেয়ে সমস্যাটিকে আরও ভাল ব্যাখ্যা করে name
মেশিনহোস্ট

1
নিয়ন্ত্রিত ইনপুট কীভাবে কাজ করে তা ব্যাখ্যা করতে আমি আমার উত্তর আপডেট করেছি। এখানে লক্ষণীয় যে এখানে যে বিষয়টি গুরুত্বপূর্ণ তা নয় যে undefinedপ্রাথমিকভাবে কোনও মান পাস হচ্ছে। বরং এটি সত্য যে this.state.nameকোনও স্টেট ভেরিয়েবল হিসাবে বিদ্যমান নেই যা ইনপুটটিকে নিয়ন্ত্রণহীন করে তোলে। উদাহরণস্বরূপ, থাকার this.state = { name: undefined };ফলে ইনপুটটি নিয়ন্ত্রণ করা হবে। এটি বোঝা উচিত যে মূল্যটি যেখানে আসে সে থেকে মূল্য কী আসে তা নয়।
fvgs

1
@fvgs- এর this.state = { name: undefined }ফলে এখনও একটি অনিয়ন্ত্রিত ইনপুট আসবে। <input value={this.state.name} />desugars যাও React.createElement('input', {value: this.state.name})। কারণ একটি বস্তুর আয় একটি অবাস্তব সম্পত্তি অ্যাক্সেস undefined, সঠিক একই ফাংশন call- এই মূল্যায়ণ React.createElement('input', {value: undefined})-whether nameসেট না করা হয় বা স্পষ্টভাবে সেট undefined, তাই একই ভাবে আচরণ করবে প্রতিক্রিয়া। আপনি এই জেএসফিডেলে এই আচরণটি দেখতে পারেন।
লেহে ব্রেনেককি

52

এটি আপনার ইনপুটটির ভিতরে ডিফল্ট মান নির্ধারণ করতে পারে এমন অন্য পদ্ধতির:

 <input name="name" type="text" value={this.state.name || ''} onChange={this.onFieldChange('name').bind(this)}/>

1
<ইনপুট নাম = "নাম" টাইপ = "পাঠ্য" defaultValue = "" onChange = {this.onFieldChange ( 'নাম') বেঁধে (এই)।} /> আমার মনে হয় would এছাড়াও কাজ
Gandalf

অনেক অনেক ধন্যবাদ, এটি ঠিক আমি খুঁজছিলাম। আমার এই প্যাটার্নটি মনে রাখা উচিত কি কোনও অসুবিধা বা সম্ভাব্য সমস্যা আছে?
মার্সেল ওটেন

এটি আমার পক্ষে কাজ করেছে, কারণ ক্ষেত্রগুলি এপিআই থেকে গতিশীলভাবে রেন্ডার করা হয় যাতে উপাদানটি মাউন্ট করা হয় তখন আমি ক্ষেত্রটির নাম জানিনা। এটি একটি ট্রিট কাজ!
জেমি - ফেনির ডিজিটাল লিমিটেড

18

আমি জানি অন্যরা এর জবাব ইতিমধ্যে দিয়েছে। তবে এখানে একটি খুব গুরুত্বপূর্ণ উপাদান যা একইরকম সমস্যা ভোগ করছে এমন অন্যান্য ব্যক্তিকে সহায়তা করতে পারে:

onChangeআপনার ইনপুট ক্ষেত্রে অবশ্যই একটি হ্যান্ডলার যুক্ত করা উচিত (যেমন টেক্সটফিল্ড, চেকবক্স, রেডিও ইত্যাদি)। সর্বদা onChangeহ্যান্ডলারের মাধ্যমে ক্রিয়াকলাপ পরিচালনা করুন।

উদাহরণ:

<input ... onChange={ this.myChangeHandler} ... />

আপনি যখন চেকবাক্স নিয়ে কাজ করছেন তখন আপনাকে এর checkedঅবস্থাটি এর সাথে পরিচালনা করতে হতে পারে !!

উদাহরণ:

<input type="checkbox" checked={!!this.state.someValue} onChange={.....} >

তথ্যসূত্র: https://github.com/facebook/react/issues/6779#issuecomment-326314716


1
এটি আমার জন্য কাজ করে, ধন্যবাদ, হ্যাঁ, আমি এটির সাথে 100% শতাংশ একমত, প্রাথমিক অবস্থা {checked, তাই পরীক্ষিত মানটি সংজ্ঞায়িত হবে এবং এটি অনিয়ন্ত্রিত করে তুলবে
পিং ওয়া

13

এই সমস্যাটি সমাধানের সহজ সমাধান হ'ল ডিফল্টরূপে একটি খালি মান সেট করা:

<input name='myInput' value={this.state.myInput || ''} onChange={this.handleChange} />

8

কনস্ট্রাক্টরের ক্ষেত্রে ক্ষেত্রের মান "" (খালি স্ট্রিং) নির্ধারণের একটি সম্ভাব্য অবক্ষয় হ'ল যদি ক্ষেত্রটি fieldচ্ছিক ক্ষেত্র হয় এবং আনডিট করা না থাকে। আপনি যদি আপনার ফর্ম পোস্ট করার আগে কিছু ম্যাসেজ না করেন তবে ক্ষেত্রটি আপনার ডেটা স্টোরেজে NULL এর পরিবর্তে খালি স্ট্রিং হিসাবে অবিরত থাকবে।

এই বিকল্পটি খালি স্ট্রিংগুলি এড়িয়ে চলবে:

constructor(props) {
    super(props);
    this.state = {
        name: null
    }
}

... 

<input name="name" type="text" value={this.state.name || ''}/>

6

আপনি যখন onChange={this.onFieldChange('name').bind(this)}নিজের ইনপুটটিতে ব্যবহার করবেন তখন আপনাকে অবশ্যই নিজের ক্ষেত্রের খালি স্ট্রিংটিকে সম্পত্তি ক্ষেত্রের মান হিসাবে ঘোষণা করতে হবে।

ভুল উপায়:

this.state ={
       fields: {},
       errors: {},
       disabled : false
    }

সঠিক পথ:

this.state ={
       fields: {
         name:'',
         email: '',
         message: ''
       },
       errors: {},
       disabled : false
    }

6

আমার ক্ষেত্রে, আমি সত্যিই তুচ্ছ কিছু অনুভব করছিলাম।

<input value={state.myObject.inputValue} />

আমি যখন সতর্কতা পেয়েছিলাম তখন আমার রাষ্ট্রটি নিম্নলিখিত ছিল:

state = {
   myObject: undefined
}

আমার মূল্যকে ইনপুট রেফারেন্স হিসাবে আমার রাষ্ট্রটি পরিবর্তন করে , আমার সমস্যাটি সমাধান করা হয়েছিল:

state = {
   myObject: {
      inputValue: ''
   }
}

2
আমার আসল সমস্যাটি বুঝতে সাহায্য করার জন্য আপনাকে ধন্যবাদ
রোটিমি-সেরা

3

যদি আপনার উপাদানগুলির প্রপসগুলি একটি রাষ্ট্র হিসাবে পাস করা হয় তবে আপনার ইনপুট ট্যাগগুলির জন্য একটি ডিফল্ট মান দিন

<input type="text" placeholder={object.property} value={object.property ? object.property : ""}>


3

এটির জন্য একটি আপডেট। প্রতিক্রিয়া হুক ব্যবহারের জন্যconst [name, setName] = useState(" ")


ধন্যবাদ 4 আপডেট জর্ডান, এই ত্রুটিটি সমাধান করা কিছুটা শক্ত
জুয়ান সালভাদোর

কেন " "এবং না ""? এটি আপনাকে যে কোনও ইঙ্গিতযুক্ত পাঠ্য হারাতে পারে এবং আপনি ক্লিক করে টাইপ করলে কোনও তথ্য প্রবেশের আগে আপনি একটি ছদ্মবেশী স্থান পান।
জোশুয়া ওয়েড

1

এটি কেবল তখনই ঘটে যখন আপনি ফাইলটি প্রয়োগের মানটি নিয়ন্ত্রণ করছেন না যখন অ্যাপ্লিকেশন শুরু হয় এবং কোনও অনুষ্ঠানের পরে বা কিছু ফাংশন সরিয়ে ফেলা বা রাষ্ট্র পরিবর্তিত হয়, আপনি এখন ইনপুট ক্ষেত্রে মানটি নিয়ন্ত্রণ করার চেষ্টা করছেন।

ইনপুটটির উপর নিয়ন্ত্রণ না রাখার এবং তারপরে এটি নিয়ন্ত্রণের এই রূপান্তরটিই এই সমস্যাটিকে প্রথমে ঘটায়।

এটি এড়ানোর সর্বোত্তম উপায় হল উপাদানটির কনস্ট্রাক্টরের ইনপুটটির জন্য কিছু মান ঘোষণা করা। যাতে অ্যাপ্লিকেশন শুরু থেকে ইনপুট উপাদানটির মান থাকে।


0

ফর্ম ইনপুটগুলির জন্য গতিশীলভাবে রাষ্ট্রীয় বৈশিষ্ট্য নির্ধারণ এবং সেগুলি নিয়ন্ত্রিত রাখার জন্য আপনি এরকম কিছু করতে পারেন:

const inputs = [
    { name: 'email', type: 'email', placeholder: "Enter your email"},
    { name: 'password', type: 'password', placeholder: "Enter your password"},
    { name: 'passwordConfirm', type: 'password', placeholder: "Confirm your password"},
]

class Form extends Component {
  constructor(props){
    super(props)
    this.state = {} // Notice no explicit state is set in the constructor
  }

  handleChange = (e) => {
    const { name, value } = e.target;

    this.setState({
      [name]: value
    }
  }

  handleSubmit = (e) => {
    // do something
  }

  render() {
     <form onSubmit={(e) => handleSubmit(e)}>
       { inputs.length ?
         inputs.map(input => {
           const { name, placeholder, type } = input;
           const value = this.state[name] || ''; // Does it exist? If so use it, if not use an empty string

           return <input key={name}  type={type} name={name} placeholder={placeholder} value={value} onChange={this.handleChange}/>
       }) :
         null
       }
       <button type="submit" onClick={(e) => e.preventDefault }>Submit</button>
     </form>    
  }
}

0

এই.স্টেট.নামটি নাল হলে কেবল '' এ ফ্যালব্যাক তৈরি করুন।

<input name="name" type="text" value={this.state.name || ''} onChange={this.onFieldChange('name').bind(this)}/>

এটি ইউজস্টেট ভেরিয়েবলগুলির সাথেও কাজ করে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.