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

2
fields상태 의 초기 값은 얼마입니까?
Mayank Shukla

2
생성자 (props) {super (props); this.state = {필드 : {}, 오류 : {}} this.onSubmit = this.onSubmit.bind (this); }
리야 카 푸리아

답변:


650

그 이유는 다음과 같이 정의한 상태입니다.

this.state = { fields: {} }

그래서 처음 렌더링 동안 빈 객체로 필드는 this.state.fields.nameundefined, 입력 필드의 값을 얻을 것이다 :

value={undefined}

이로 인해 입력 필드가 제어되지 않습니다.

입력에 값을 입력하면 fields상태가 다음으로 변경됩니다.

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

그 당시 입력 필드는 제어 된 구성 요소로 변환됩니다. 그래서 오류가 발생합니다.

구성 요소가 제어 할 텍스트 유형의 제어되지 않은 입력을 변경하고 있습니다.

가능한 해결책:

1- fields상태를 다음과 같이 정의하십시오 .

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

2- 또는 다음 과 같이 단락 평가 를 사용하여 값 속성을 정의하십시오 .

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

5
undefined가 "uncontrolled"인 반면 후자가 "controlled"인 이유는 무엇입니까?
Prashanth Subramanian

2
''유효한 문자열 값 이기 때문 입니다. 따라서 '''xyz'로 변경 하면 입력 유형이 제어 됨으로 제어됨을 변경하지 않습니다. 그러나 경우 undefinedxyz형 제어되지 않는에서 제어로 변경됩니다.
Mayank Shukla 2018

1
감사합니다.이 작업은 다음과 같습니다.value={this.state.fields.name || ''}
Bob

1
일단 값이 정의되지 않으면 입력이 자동으로 제어되지 않는다는 것을 알지 못했습니다. 이미 내 문제를 해결
Adrian Serna

1
놀랄 만한! 공식 문서에 언급되지 않았거나 장님입니까? 소스로 연결하십시오 :)
Dheeraj

34

변경 value하려면 defaultValue그것을 해결됩니다.

참고 :

defaultValue초기로드에만 해당됩니다. 를 초기화하려면 input을 사용해야 defaultValue하지만 state값을 변경하는 데 사용하려면을 사용해야 value합니다. 자세한 내용 을 읽으십시오 .

나는 그 경고를 없애기 위해 사용 value={this.state.input ||""}했습니다 input.


2
감사합니다! 나는이 문제를 겪었고 다른 솔루션은 나에게 적용되지 않았지만이 솔루션이 도움이되었습니다.
PepperAddict

14

구성 요소 내부에 다음과 같은 방법으로 입력 상자를 넣습니다.

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

13

간단하게, 초기 상태를 먼저 설정해야합니다

초기 상태를 설정하지 않으면 react가 제어되지 않는 구성 요소 로 취급합니다.


10

허용 된 답변 외에도 또는 input유형을 사용하는 경우 속성 을 null / undefined로 확인해야한다는 것을 알았 습니다.checkboxradiochecked

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

그리고 TS (또는 Babel)를 사용하는 경우 논리 OR 연산자 대신 nullish 병합을 사용할 수 있습니다.

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

8

현재 상태를 먼저 설정 ...this.state

새 상태를 할당하려고 할 때 정의되지 않을 수 있기 때문입니다. 상태 추출 현재 상태를 설정하여 고정됩니다.

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

상태에 객체가있는 경우 상태를 다음과 같이 설정해야합니다. 사용자 객체 내부에 사용자 이름을 설정해야한다고 가정합니다.

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

1
내가 이해하는 한 setState는 이미 필드 만 재정의하므로 첫 번째 경우 할당을 해제해야합니다. 두 번째 상태에서는 setState가 하위 오브젝트 도매를 대체하기 때문에 필요할 수 있습니다.
Kzqai 2016 년

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

React Hooks를 사용하는 것도 초기 값을 설정하는 것을 잊지 마십시오.
나는 사용 <input type='datetime-local' value={eventStart} />하고 있었고 초기 eventStart는 같았다.

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

괄호 안의 빈 문자열은 차이입니다.
또한 제출 한 것처럼 양식을 다시 설정하면 빈 괄호가 아닌 빈 문자열로 다시 설정해야합니다.

이것은이 주제에 대한 나의 작은 기여 일뿐입니다. 아마도 누군가를 도울 것입니다.


0

필자의 경우 Mayank Shukla의 최고 답변이 말한 것과 거의 같습니다. 유일한 세부 사항은 내 주가 내가 정의한 재산이 완전히 부족하다는 것입니다.

예를 들어,이 상태 인 경우 :

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>

내가 tryed ({ valueName, valueName: {geschlecht=""}, onChangeAllg,})value={valueName.geschlecht || ""}


찾았어요. defaultValue={""}는 TextField의 내부가 누락 된
박사 말테 Westerloh

0

경고 : 구성 요소가 제어 할 텍스트 유형의 제어되지 않은 입력을 변경하고 있습니다. 입력 요소는 제어되지 않은 상태에서 제어 된 상태로 또는 그 반대로 전환해서는 안됩니다. 구성 요소의 수명 동안 제어 또는 제어되지 않은 입력 요소 사용 여부를 결정하십시오.

솔루션 : 값이 정의되지 않았는지 확인

반응 / Formik / 부트 스트랩 / TypeScript

예 :

{ values?.purchaseObligation.remainingYear ?
  <Input
   tag={Field}
   name="purchaseObligation.remainingYear"
   type="text"
   component="input"
  /> : null
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.