Любопытно, как правильно подойти к этому:
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 для обработки каждого ввода, но это не очень хорошо. Точно так же вы можете создать компонент только для отдельного ввода, но я хотел посмотреть, есть ли способ сделать это таким образом.
javascript
reactjs
jsx
T3db0t
источник
источник
Ответы:
Я предлагаю придерживаться стандартных атрибутов HTML как
name
наinput
элементах , чтобы определить свои входы. Кроме того, вам не нужно сохранять «total» как отдельное значение в состоянии, потому что оно может быть составлено путем добавления других значений в ваше состояние: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'));
источник
this.setState({ [e.target.name]: e.target.value });
Вы можете использовать
.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
расчет во время рендеринга, так как это рекомендуется делать.)источник
this.handleChange.bind(...)
создающее новую функцию. Если вы используетеshouldComponentUpdate
withPureRenderMixin
или что-то подобное, он сломается. Все ваши входные компоненты будут повторно отображены при изменении одного значения.handleChange
на,handleChange(name) { return event => this.setState({name: event.target.value}); }
вы можете передать «ту же» функцию (не будет создавать новую функцию, как это делается с помощью.bind()
Then, вы можете передать такую функцию:this.handleChange("input1")
this.setState(change, function () { console.log(this.state.input1); );
reference: stackoverflow.com/questions/30782948/…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}) }
Я использую нечто подобное в нескольких приложениях, и это очень удобно.
источник
Устаревшее решение
valueLink/checkedLink
являются устаревшими из ядра React, потому что это сбивает с толку некоторых пользователей. Этот ответ не сработает, если вы используете последнюю версию 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
Вы даже можете реализовать свой собственный миксин
источник
Вы также можете сделать это так:
... 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> ) }
источник
[]
вокругinput
в SetState.Вы можете использовать специальный
React
атрибут ,ref
а затем сопоставить узлы реального DOM вonChange
случае использованияReact
«sgetDOMNode()
функции: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> ... }
источник
prev
это просто имя, которое я установил вrender()
методеevent.target === this.refs.prev
. facebook.github.io/react/blog/2015/10/07/…@Vigril Disgr4ce
Когда дело доходит до многопольных форм, имеет смысл использовать ключевую функцию React: компоненты.
В своих проектах я создаю компоненты TextField, которые принимают как минимум свойство value и заботятся об общем поведении текстового поля ввода. Таким образом, вам не нужно беспокоиться об отслеживании имен полей при обновлении состояния значения.
[...] 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} />; } [...]
источник
Вы можете отслеживать значение каждого дочернего элемента,
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
компонента без создания отдельных значений в родительском состоянии для отслеживания каждого дочернего компонента.источник
Я предложу действительно простое решение проблемы. Предположим, у нас есть два входа
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.Наш конструктор, который мы хотим сохранить
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.Прите обнаружение Изменения
onChange(event)
называется2.Затем мы получаем параметр имени поля и его значение:
let inputName = event.target.name; ex: username
let value = event.target.value; ex: itsgosho
3. На основе параметра name мы получаем наше значение из состояния в конструкторе и обновляем его значением:
this.state['username'] = 'itsgosho'
4. Здесь важно отметить, что имя поля должно совпадать с нашим параметром в состоянии
Надеюсь, я как-то помог кому-то :)
источник
Ключ вашего состояния должен совпадать с именем вашего поля ввода. Затем вы можете сделать это в методе handleEvent;
this.setState({ [event.target.name]: event.target.value });
источник
Привет улучшил 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'));
источник