Mam następujący składnik ( 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>
)
}
};
Przed użyciem ECMAScript6 wszystko było dobrze, teraz pojawia się 1 błąd, 1 ostrzeżenie i mam dodatkowe pytanie:
Błąd: Uncaught TypeError: Nie można odczytać właściwości „otherChecked” wartości null
Ostrzeżenie: getInitialState zostało zdefiniowane w RadioOther, zwykłej klasie JavaScript. Jest to obsługiwane tylko dla klas utworzonych za pomocą React.createClass. Czy zamiast tego chodziło Ci o zdefiniowanie własności państwowej?
Czy ktoś może zobaczyć, gdzie leży błąd, wiem, że wynika to z instrukcji warunkowej w DOM, ale najwyraźniej nie deklaruję poprawnie jego wartości początkowej?
Czy powinienem ustawić getInitialState jako statyczne
Gdzie jest odpowiednie miejsce do zadeklarowania moich właściwości, jeśli getInitialState nie jest poprawne?
AKTUALIZACJA:
RadioOther.propTypes = {
name: React.PropTypes.string,
other: React.PropTypes.bool,
options: React.PropTypes.array }
module.exports = RadioOther;
@ssorallen, ten kod:
constructor(props) {
this.state = {
otherChecked: false,
};
}
produkuje "Uncaught ReferenceError: this is not defined"
, a poniżej poprawia to
constructor(props) {
super(props);
this.state = {
otherChecked: false,
};
}
ale teraz kliknięcie drugiego przycisku powoduje teraz błąd:
Uncaught TypeError: Cannot read property 'props' of undefined
źródło
onChange={this.onRadChange}
,this
nie odnosi się do instancji, gdyonRadChange
jest wywoływana. Trzeba callbacków powiązań wrender
lub zrobić go w konstruktorze:onChange={this.onRadChange.bind(this)}
.Odpowiedzi:
getInitialState
nie jest używany w klasach ES6. Zamiast tego przypiszthis.state
w konstruktorze.propTypes
powinien być statyczną zmienną klasy lub przypisany do klasy, nie powinien być przypisywany do instancji komponentów.Zobacz więcej w dokumentacji Reacta o klasach ES6: Converting a Function to a Class
źródło
Uncaught TypeError: Cannot read property 'bind' of undefined
błąd Jakieś pomysły?render
że możesz zrobić coś podobnegoonClick={this.doFoo.bind(this)}
, ale celowo nie włączyłem tego do kodu, ponieważ jest to najmniej efektywny sposób wiązania, ponieważrender
może być często wywoływany i tworzył nowe funkcje przy każdym wywołaniu. Usunę ten język z odpowiedzi.Dodając do odpowiedzi Rossa .
Możesz także użyć nowej funkcji strzałki ES6 we właściwości onChange
Funkcjonalnie odpowiada definiowaniu
this.onRadChange = this.onRadChange.bind(this);
w konstruktorze, ale moim zdaniem jest bardziej zwięzłe.W twoim przypadku przycisk opcji będzie wyglądał jak poniżej.
Aktualizacja
Ta „bardziej zwięzła” metoda jest mniej wydajna niż opcje wymienione w odpowiedzi @Ross Allen, ponieważ generuje nową funkcję za każdym razem, gdy
render()
metoda jest wywoływanaźródło
render
(która może być wywoływana wiele razy). Używając inicjatora właściwości klasy lub powiązania w konstruktorze, tylko jedna nowa powiązana funkcja jest tworzona podczas konstruowania składnika i nie są tworzone żadne nowe funkcje podczasrender
.Jeśli używasz babel-plugin-transform-class-properties lub babel-preset-stage-2 (lub stage-1 lub stage-0), możesz użyć następującej składni:
źródło