React.js : 하나의 onChange 핸들러로 다른 입력 식별


142

이것에 접근하는 올바른 방법이 무엇인지 궁금합니다.

var Hello = React.createClass({
getInitialState: function() {
    return {total: 0, input1:0, input2:0};
},
render: function() {
    return (
        <div>{this.state.total}<br/>
            <input type="text" value={this.state.input1} onChange={this.handleChange} />
            <input type="text" value={this.state.input2} onChange={this.handleChange} />
        </div>
    );
},
handleChange: function(e){
    this.setState({ ??? : e.target.value});
    t = this.state.input1 + this.state.input2;
    this.setState({total: t});
}
});

React.renderComponent(<Hello />, document.getElementById('content'));

분명히 각각의 다른 입력을 처리하기 위해 별도의 handleChange 함수를 만들 수는 있지만 그리 좋지는 않습니다. 마찬가지로 개별 입력에 대해서만 구성 요소를 만들 수는 있지만 이와 같은 방법이 있는지 확인하고 싶었습니다.

답변:


163

처럼 표준 HTML 속성을 고수 제안 nameinput당신의 입력을 식별하는 요소. 또한 상태에 다른 값을 추가하여 구성 할 수 있으므로 "전체"를 상태의 별도 값으로 유지할 필요가 없습니다.

var Hello = React.createClass({
    getInitialState: function() {
        return {input1: 0, input2: 0};
    },
    render: function() {
        const total = this.state.input1 + this.state.input2;

        return (
            <div>{total}<br/>
                <input type="text" value={this.state.input1} name="input1" onChange={this.handleChange} />
                <input type="text" value={this.state.input2} name="input2" onChange={this.handleChange} />
            </div>
        );
    },
    handleChange: function(e) {
        this.setState({[e.target.name]: e.target.value});
    }
});

React.renderComponent(<Hello />, document.getElementById('content'));

3
처음에이 작업을 시도했지만 setState ({e.target.name ...이 작동하지 않습니다. 구문 오류입니다. obj [e.target.name] 및 setState를 사용하여 임시 객체를 만들어야합니다. 이런 종류의 작품이지만, 상태 객체 업데이트에는 약간의 지연이있는 것 같습니다.
T3db0t

1
"지연의 종류"는 requestAnimationFrame 동안 setState 업데이트 (따라 가정)이므로 무시하십시오.
T3db0t

24
@ T3db0t이 ES6 구문은 다음과 같이 작동합니다.this.setState({ [e.target.name]: e.target.value });
XåpplI'-I0llwlg'I-

2
바인드를 사용하는 것이 더 좋습니다. div와 같은 name 속성이없는 요소에 onChange 핸들러를 연결하면이 방법이 작동하지 않습니다.
ericgrosse

3
이 경우 @ericgrosse 바인드는 많은 불필요한 기능을 생성하므로 더 좋지 않습니다. 또한 필요한 경우 다른 종류의 요소에 데이터 속성 또는 무언가를 사용할 수 있습니다.
aw04

106

.bind메소드를 사용하여 메소드에 대한 매개 변수를 사전 빌드 할 수 있습니다 handleChange. 다음과 같습니다.

  var Hello = React.createClass({
    getInitialState: function() {
        return {input1:0, 
                input2:0};
    },
    render: function() {
      var total = this.state.input1 + this.state.input2;
      return (
        <div>{total}<br/>
          <input type="text" value={this.state.input1} 
                             onChange={this.handleChange.bind(this, 'input1')} />
          <input type="text" value={this.state.input2} 
                             onChange={this.handleChange.bind(this, 'input2')} />
        </div>
      );
    },
    handleChange: function (name, e) {
      var change = {};
      change[name] = e.target.value;
      this.setState(change);
    }
  });

  React.renderComponent(<Hello />, document.getElementById('content'));

( total추천하는 것이기 때문에 렌더 타임에 계산되었습니다.)


13
this.handleChange.bind(...)새로운 기능 을 만드는 간단한 알림입니다 . shouldComponentUpdate함께 사용 PureRenderMixin하거나 비슷한 것을 사용하면 깨질 것입니다. 단일 값이 변경되면 모든 입력 구성 요소가 다시 렌더링됩니다.
zemirco

5
당신의 구현을 변경하는 경우 handleChangehandleChange(name) { return event => this.setState({name: event.target.value}); }당신은 "동일한"기능을 전달할 수를 (그것이 사용하여 수행 할 것 같은 새로운 기능을 만들지 않습니다 .bind()그런를, 당신은 같은 기능을 전달할 수 있습니다this.handleChange("input1")
Andreyco

1
setState의 본질은 handChange 함수에서 현재 상태를 검색 할 수 없지만 this.state.input1을 사용하는 이전 상태를 검색 할 수 없다는 것입니다. 적절한 접근 방법은 다음과 같은 콜백을 만드는 것입니다 this.setState(change, function () { console.log(this.state.input1); );: stackoverflow.com/questions/30782948/…
Charlie-Greenman

39

onChange이벤트는 거품 ... 당신이 뭔가를 할 수 있습니다 :

// A sample form
render () {
  <form onChange={setField}>
    <input name="input1" />
    <input name="input2" />
  </form>
}

그리고 setField 메소드는 다음과 같습니다 (ES2015 이상을 사용한다고 가정합니다).

setField (e) {
  this.setState({[e.target.name]: e.target.value})
}

여러 앱에서 이와 비슷한 것을 사용하며 매우 편리합니다.


11

더 이상 사용되지 않는 솔루션

valueLink/checkedLink되어 사용되지 는 일부 사용자를 혼란 때문에 핵심에서이 반응한다. 최신 버전의 React를 사용하면이 답변이 작동하지 않습니다. 그러나 원하는 경우 고유 한 Input구성 요소 를 만들어 쉽게 에뮬레이션 할 수 있습니다.

기존 답변 내용 :

React의 양방향 데이터 바인딩 도우미를 사용하면 훨씬 쉽게 달성 할 수 있습니다.

var Hello = React.createClass({
    mixins: [React.addons.LinkedStateMixin],
    getInitialState: function() {
        return {input1: 0, input2: 0};
    },

    render: function() {
        var total = this.state.input1 + this.state.input2;
        return (
            <div>{total}<br/>
                <input type="text" valueLink={this.linkState('input1')} />;
                <input type="text" valueLink={this.linkState('input2')} />;
            </div>
        );
    }

});

React.renderComponent(<Hello />, document.getElementById('content'));

쉬운가요?

http://facebook.github.io/react/docs/two-way-binding-helpers.html

자신 만의 믹스 인을 구현할 수도 있습니다


상태를 설정하기 위해 onchange를 바인딩해야하는 이유는 무엇입니까? 결국 ReactJS입니다!
Junaid Qadir

이 솔루션은 더 이상 사용되지 않습니다.
Philipp

6

다음과 같이 할 수도 있습니다 :

...
constructor() {
    super();
    this.state = { input1: 0, input2: 0 };
    this.handleChange = this.handleChange.bind(this);
}

handleChange(input, value) {
    this.setState({
        [input]: value
    })
}

render() {
    const total = this.state.input1 + this.state.input2;
    return (
        <div>
            {total}<br />
            <input type="text" onChange={e => this.handleChange('input1', e.target.value)} />
            <input type="text" onChange={e => this.handleChange('input2', e.target.value)} />
        </div>
    )
}

나를 위해 일하지 않았다. React 개발자 도구를 보았습니다. input1 / input2 대신 input이라는 변수 / 객체에 값을 생성하고 할당
Gaurravs

1
@Gaurravs 네 맞아요. 내가 추가 할 필요가 []주위 input와 setState로. 이 속성은 동적으로 할당됩니다
inostia

4

의 특수 React속성을 사용한 ref다음 의 함수를 onChange사용 하여 이벤트 의 실제 DOM 노드와 일치 시킬 수 있습니다 .ReactgetDOMNode()

handleClick: function(event) {
  if (event.target === this.refs.prev.getDOMNode()) {
    ...
  }
}

render: function() {
  ...
  <button ref="prev" onClick={this.handleClick}>Previous question</button>
  <button ref="next" onClick={this.handleClick}>Next question</button>
  ...
}

적어도 0.13에서 this.refs는 pref.
blub

2
@usagidon- prevrender()방법으로 설정 한 이름
일뿐입니다

2
React v0.14부터는 할 수 있습니다 event.target === this.refs.prev. facebook.github.io/react/blog/2015/10/07/…
XåpplI'-I0llwlg'I-

0

짤방 백업 봇

다중 필드 형식에 대해서는 React의 주요 기능인 구성 요소를 사용하는 것이 좋습니다.

내 프로젝트에서 TextField 구성 요소를 작성하여 최소한 값 prop를 가져오고 입력 텍스트 필드의 일반적인 동작을 처리합니다. 이렇게하면 값 상태를 업데이트 할 때 필드 이름을 추적 할 필요가 없습니다.

[...]

handleChange: function(event) {
  this.setState({value: event.target.value});
},
render: function() {
  var value = this.state.value;
  return <input type="text" value={value} onChange={this.handleChange} />;
}

[...]

0

단일 값을 관리 input하는 별도의 InputField구성 요소를 만들어 각 자식의 값을 추적 할 수 있습니다 input. 예를 들어 다음과 InputField같습니다.

var InputField = React.createClass({
  getInitialState: function () {
    return({text: this.props.text})
  },
  onChangeHandler: function (event) {
     this.setState({text: event.target.value})
  }, 
  render: function () {
    return (<input onChange={this.onChangeHandler} value={this.state.text} />)
  }
})

이제 각 하위 구성 요소를 모니터링하기 위해 부모 상태에서 별도의 값을 만들지 않고도이 구성 요소 input의 개별 인스턴스 내에서 각 값을 추적 할 수 있습니다 InputField.


0

나는 문제에 대한 간단한 해결책을 제시 할 것이다. 두 개의 입력이 username있고password , 그러나 우리는 우리가 그것을 재사용 및 쓰기 상용구 코드를하지 할 수 있도록 우리의 핸들이 쉽고 일반적인되고 싶어요.

I. 우리의 형태 :

                <form>
                    <input type="text" name = "username" onChange={this.onChange} value={this.state.username}/>
                    <input type="text" name = "password" onChange={this.onChange} value={this.state.password}/>
                    <br></br>
                    <button type="submit">Submit</button>
                </form>

우리가 우리 저장할 II.Our 생성자, username그리고 password우리가 쉽게 액세스 할 수 있도록 :

constructor(props) {
    super(props);
    this.state = {
        username: '',
        password: ''
    };

    this.onSubmit = this.onSubmit.bind(this);
    this.onChange = this.onChange.bind(this);
}

III. onChange이벤트가 하나 뿐인 흥미롭고 "일반적인"핸들 은 다음을 기반으로합니다.

onChange(event) {
    let inputName = event.target.name;
    let value = event.target.value;

    this.setState({[inputName]:value});


    event.preventDefault();
}

설명하겠습니다 :

변화가 검출 1.When onChange(event)라고

그런 다음 필드의 이름 매개 변수와 그 값을 얻습니다.

let inputName = event.target.name; ex: username

let value = event.target.value; ex: itsgosho

3. name 매개 변수를 기준으로 생성자의 상태에서 값을 가져와 값으로 업데이트합니다.

this.state['username'] = 'itsgosho'

4. 여기서 주목할 점은 필드 이름이 해당 상태의 매개 변수와 일치해야한다는 것입니다.

내가 어떻게 든 누군가를 돕기를 바랍니다 :)


0

상태의 키는 입력 필드의 이름과 같아야합니다. 그런 다음 handleEvent 메소드에서이를 수행 할 수 있습니다.

this.setState({
        [event.target.name]: event.target.value
});

-1

안녕하세요 ssorallen 답변 을 개선 했습니다 . 입력없이 입력에 액세스 할 수 있으므로 기능을 바인딩 할 필요가 없습니다.

var Hello = React.createClass({
    render: function() {
        var total = this.state.input1 + this.state.input2;
        return (
             <div>{total}<br/>
                  <input type="text" 
                    value={this.state.input1}
                    id="input1"  
                    onChange={this.handleChange} />
                 <input type="text" 
                    value={this.state.input2}
                    id="input2" 
                    onChange={this.handleChange} />
            </div>
       );
   },
   handleChange: function (name, value) {
       var change = {};
       change[name] = value;
       this.setState(change);
   }
});

React.renderComponent(<Hello />, document.getElementById('content'));
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.