Bir bileşen ReactJS'de denetlenecek hata metni tipinde kontrolsüz bir girişi değiştiriyor


331

Uyarı: Bir bileşen, kontrol edilecek tip metinlerin kontrolsüz bir girişini değiştiriyor. Giriş elemanları kontrolsüzden kontrollü (veya tam tersi) olmamalıdır. Bileşenin ömrü boyunca kontrollü veya kontrolsüz giriş öğesi kullanma arasında karar verin. *

Kodum aşağıdadır:

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

2
fieldseyaletteki başlangıç ​​değeri nedir?
Mayank Shukla

2
yapıcı (sahne) {süper (sahne); this.state = {alanlar: {}, hatalar: {}} this.onSubmit = this.onSubmit.bind (this); }
Riya Kapuria

Yanıtlar:


650

Sebebi, tanımladığınız durumda:

this.state = { fields: {} }

bu yüzden ilk oluşturulması sırasında boş bir nesne olarak alanlar, this.state.fields.nameolacak undefinedve giriş alanı değerini olarak alacak:

value={undefined}

Bu nedenle, giriş alanı kontrolsüz hale gelecektir.

Girişe herhangi bir değer girdiğinizde, fieldsdurum şu şekilde değiştirilir:

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

Ve o zaman girdi alanı kontrollü bir bileşene dönüştürülür; bu yüzden hatayı alıyorsunuz:

Bir bileşen, kontrol edilecek metin türünün kontrolsüz bir girişini değiştiriyor.

Olası çözümler:

1- fieldsDurumunu şu şekilde tanımlayın :

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

2- Veya aşağıdaki gibi Kısa devre değerlendirmesini kullanarak değer özelliğini tanımlayınız :

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

5
"kontrolsüz" iken tanımsızın "kontrolsüz" olmasının bir nedeni var mı - bunlar ne anlama geliyor?
Prashanth Subramanian

2
çünkü ''geçerli bir dize değeridir. bu nedenle '''xyz' olarak değiştirdiğinizde , giriş türü değişmiyor kontrollü olarak kontrol edilir. Ama durumunda undefinedetmek xyztip kontrolsüz kontrol değişecektir.
Mayank Shukla

1
Teşekkür ederim bu benim için çalıştı:value={this.state.fields.name || ''}
Bob

1
Değer tanımsız hale geldiğinde, girdinin otomatik olarak kontrolsüz hale geldiğini bilmiyordum, Harika. Zaten benim sorunumu düzeltmek
Adrian Serna

1
inanılmaz! çünkü bunu resmi dokümanlarda görmedim, yoksa kör müyüm? kaynağa bağlantı lütfen :)
Dheeraj

34

Değişen valueiçin defaultValuebunu çözecektir.

Not :

defaultValuesadece ilk yükleme içindir. Başlatırsanız inputo zaman kullanmalısınız defaultValue, ancak statedeğeri değiştirmek için kullanmak istiyorsanız kullanmanız gerekir value. Daha fazlası için bunu okuyun .

Kullandığım value={this.state.input ||""}içinde inputo uyarı kurtulmak için.


2
Teşekkür ederim! Bu sorunla karşılaştım ve diğer çözümler benim için geçerli değildi, ancak bu çözüm yardımcı oldu.
PepperAddict

14

Bileşenin içine giriş kutusunu aşağıdaki şekilde yerleştirin.

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

13

SADECE, önce başlangıç ​​durumunu ayarlamanız gerekir

Başlangıç ​​durumu reaksiyonunu ayarlamazsanız, bunu kontrolsüz bir bileşen olarak görür


10

Kabul edilen cevaba ek olarak, bir inputtür kullanıyorsanız checkboxveya radionull / undefined checkedözelliğini de kontrol etmem gerektiğini buldum .

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

TS (veya Babel) kullanıyorsanız, mantıksal OR operatörü yerine nullish birleştirme kullanabilirsiniz:

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

8

Önce Geçerli Durumu Ayarla ...this.state

Çünkü yeni bir durum atayacağınız zaman tanımsız olabilir. böylece durum çıkarma akım durumu da ayarlanarak sabitlenecektir

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

Durumunuzda bir nesne varsa, durumu aşağıdaki gibi ayarlamanız gerekir; kullanıcı nesnesinin içinde kullanıcı adı ayarlamanız gerektiğini varsayalım.

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

1
Anladığım kadarıyla, setState zaten sadece alanları geçersiz kılar, bu nedenle ilk durumda atamayı imha etmek gereksizdir. İkinci durumda, setState bir alt nesne toptancısının yerini alacağından gerekli olabilir.
Kzqai

6
const [name, setName] = useState()

metin alanına yazdığınızda hata üretir

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

sorunu bu dize örneğinde düzeltir.


2

Açık alanda birden fazla giriş kullanıyorsanız aşağıdakileri uygulayın: Örneğin:

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

Sorununuzu şurada arayın:

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

1

Reaksiyon Kancalarını kullanmak da başlangıç ​​değerini ayarlamayı unutmayın.
Kullanıyordum <input type='datetime-local' value={eventStart} />ve ilk eventStartşey gibiydi

const [eventStart, setEventStart] = useState();
yerine
const [eventStart, setEventStart] = useState('');.

Parantez içindeki boş dize farktır.
Ayrıca, benim gibi gönderdikten sonra formu sıfırlarsanız, yalnızca boş parantez için değil, boş dizeye ayarlamanız gerekir.

Bu sadece bu konuya yaptığım küçük katkı, belki birine yardım edecek.


0

Benim durumumda Mayank Shukla'nın en büyük cevabı söylüyordu. Tek detay, devletimin tamamen tanımladığım mülkten yoksun olmasıydı.

Örneğin, bu duruma sahipseniz:

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

Kodunuzu açılıyorsanız varsa, başka, bu yüzden yere yeni bir pervane eklemek için kodunuzda yeni bir özellik yaratabilir isteyebilirsiniz c, değeri yalnızca bileşenin durumu hakkında tanımsız değil ama özellik kendisi tanımlanmamış.

Bunu çözmek için sadece cdurumunuza eklediğinizden ve ona uygun bir başlangıç ​​değeri verdiğinizden emin olun .

Örneğin,

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

Umarım son durumumu açıklayabilirim.


0

Aynı uyarıyı alıyorum: Bir bileşen, denetlenecek gizli türdeki denetlenmeyen bir girdiyi değiştiriyor. Sorunumu çözemiyorum. Neden herhangi bir fikir?

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>

denedim ({ valueName, valueName: {geschlecht=""}, onChangeAllg,})vevalue={valueName.geschlecht || ""}


buldum. Bir defaultValue={""}TextField içi eksikti
Dr Malte Westerloh

0

Uyarı: Bir bileşen, kontrol edilecek tip metinlerin kontrolsüz bir girişini değiştiriyor. Giriş elemanları kontrolsüzden kontrollü (veya tam tersi) olmamalıdır. Bileşenin ömrü boyunca kontrollü veya kontrolsüz giriş öğesi kullanma arasında seçim yapın.

Çözüm: Değerin tanımsız olup olmadığını kontrol edin

React / Formik / Önyükleme / TypeScript

misal :

{ values?.purchaseObligation.remainingYear ?
  <Input
   tag={Field}
   name="purchaseObligation.remainingYear"
   type="text"
   component="input"
  /> : null
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.