У меня есть следующий компонент (radioOther.jsx
):
'use strict';
//module.exports = <-- omitted in update
class RadioOther extends React.Component {
// omitted in update
// getInitialState() {
// propTypes: {
// name: React.PropTypes.string.isRequired
// }
// return {
// otherChecked: false
// }
// }
componentDidUpdate(prevProps, prevState) {
var otherRadBtn = this.refs.otherRadBtn.getDOMNode();
if (prevState.otherChecked !== otherRadBtn.checked) {
console.log('Other radio btn clicked.')
this.setState({
otherChecked: otherRadBtn.checked,
});
}
}
onRadChange(e) {
var input = e.target;
this.setState({
otherChecked: input.checked
});
}
render() {
return (
<div>
<p className="form-group radio">
<label>
<input type="radio"
ref="otherRadBtn"
onChange={this.onRadChange}
name={this.props.name}
value="other"/>
Other
</label>
{this.state.otherChecked ?
(<label className="form-inline">
Please Specify:
<input
placeholder="Please Specify"
type="text"
name="referrer_other"
/>
</label>)
:
('')
}
</p>
</div>
)
}
};
До использования ECMAScript6 все было хорошо, теперь я получаю 1 ошибку, 1 предупреждение, и у меня есть следующий вопрос:
Ошибка: Uncaught TypeError: невозможно прочитать свойство 'otherChecked' из null
Предупреждение: getInitialState был определен на RadioOther, простом классе JavaScript. Это поддерживается только для классов, созданных с использованием React.createClass. Вы имели в виду определить свойство состояния вместо?
Может ли кто-нибудь увидеть, где ошибка, я знаю, что это связано с условным утверждением в DOM, но, видимо, я не правильно заявляю его начальное значение?
Должен ли я сделать getInitialState static
Где подходящее место для объявления моих proptypes, если getInitialState неверно?
UPDATE:
RadioOther.propTypes = {
name: React.PropTypes.string,
other: React.PropTypes.bool,
options: React.PropTypes.array }
module.exports = RadioOther;
@ssorallen, этот код:
constructor(props) {
this.state = {
otherChecked: false,
};
}
создает "Uncaught ReferenceError: this is not defined"
, а ниже - исправляет, что
constructor(props) {
super(props);
this.state = {
otherChecked: false,
};
}
но теперь нажатие на другую кнопку вызывает ошибку:
Uncaught TypeError: Cannot read property 'props' of undefined
getInitialState
не используется в классах ES6. Вместо этого назначьте this.state
в конструкторе.propTypes
должна быть статической переменной класса или назначена классу, она не должна быть назначена экземплярам компонентов.export default class RadioOther extends React.Component {
static propTypes = {
name: React.PropTypes.string.isRequired,
};
constructor(props) {
super(props);
this.state = {
otherChecked: false,
};
}
// Class property initializer. `this` will be the instance when
// the function is called.
onRadChange = () => {
...
};
...
}
См. больше в документации React о ES6 Классы: https://facebook.github.io/react/docs/state-and-lifecycle.html#converting-a-function-to-a-class
Uncaught TypeError: Cannot read property 'bind' of undefined
ошибки. Есть идеи?
Добавив в ответ Росса.
Вы также можете использовать новую функцию ES6 arrow в свойстве onChange
Он функционально эквивалентен определению this.onRadChange = this.onRadChange.bind(this);
в конструкторе, но более кратким, на мой взгляд.
В вашем случае переключатель будет выглядеть следующим образом.
<input type="radio"
ref="otherRadBtn"
onChange={(e)=> this.onRadChange(e)}
name={this.props.name}
value="other"/>
Обновление
Этот "более сжатый" метод менее эффективен, чем варианты, упомянутые в ответе @Ross Allen, потому что он генерирует новую функцию каждый раз, когда вызывается метод render()
render
(который может быть вызван много раз). Используя инициализатор или привязку свойства класса в конструкторе, при построении компонента создается только одна новая связанная функция, а новые функции не создаются во время render
.
Если вы используете свойства babel-plugin-transform-class или babel-preset-stage-2 (или stage-1 или stage-0), вы можете использовать этот синтаксис:
class RadioOther extends React.Component {
static propTypes = {
name: React.PropTypes.string,
...
};
state = {
otherChecked: false,
};
onRadChange = () => {
...
};
...
}
onChange={this.onRadChange}
,this
не относится к экземпляру, когдаonRadChange
. Вы должны связать обратные вызовы вrender
или сделать это в конструкторе:onChange={this.onRadChange.bind(this)}
.