Как вызвать метод в другом методе в классе react Es6
Так что я в основном пытаюсь сделать, это просто
class Something extends React.Component {
validateEmail () {
//code that validates email,innerHTML a div.status element if error occurs
this.removeStatus();//then remove status onkeydown of input element
}
removeStatus () {
//code that removes the status onkeydown of input element
}
}
по какой-то причине это не работает. в моей консоли javascript (chrome) я получаю это
login.js:132Uncaught TypeError: this.removeStatus is not a function
Edit 1: я добавил фактический код, как вы можете видеть, я связываю validateEmail в конструкторе
class Email extends React.Component {
constructor(props) {
super(props);
this.change = this.change.bind(this);
this.validateEmail = this.validateEmail.bind(this);
this.state = {
value : ''
}
}
removeStatus() {
$('input').on('keydown',function () {
$('.contextual-info').fadeOut();
});
}
validateEmail(event) {
event.preventDefault();
var token = $('#token').val();
var email_regex=/^([w-]+(?:.[w-]+)*)@((?:[w-]+.)*w[w-]{0,66}).([a-z]{2,6}(?:.[a-z]{2})?)$/i;
if ($.trim(this.state.value) !== "") {
if (email_regex.test(this.state.value)) {
$.ajax({
url:'/login',
type:'post',
data:{email:this.state.value,_token:token},
success: function (response) {
if (response) {
$('#email').remove();
$('.btn').remove();
$('#status').html('');
ReactDOM.render(<Password /> ,document.getElementById('login-dialogue'));
$('input[type="password"]').focus();
} else {
$('input#email').addClass('input-context');
if($('#status').html('<div class="bg-danger contextual-info wrong">Email Address Not Found!</p>')){
this.removeStatus();
}
}
}
});
} else {
if($('#status').html('<div class="bg-danger contextual-info wrong">Invalid Email Address</div>')){
this.removeStatus();
}
}
} else {
if($('#status').html('<div class="bg-danger contextual-info wrong">Can't submit an empty field!</div>')){
this.removeStatus();
}
}
}
change (event) {
this.setState({
value : event.target.value
});
}
render(){
return(
<div className="login-dialogue" id="login-dialogue">
<h1 className="text-center">Log in</h1>
<div id="status"></div>
<form action="" onSubmit={this.validateEmail} id="validateEmail">
<input type="email" id="email" value={this.state.value} placeholder="Email Address" onChange={this.change} />
<button type="submit" className="btn btn-flat btn-wide teal white-text">Continue</button>
</form>
</div>
);
}
}
ReactDOM.render(<Email /> ,document.getElementById('flex-me'));
2 ответов
ваши методы определены правильно, поэтому проблема заключается в том, как вы вызов validateEmail
.
вы вызываете его в this
к чему-то, кроме вашего Something
экземпляра. Это распространено в прослушивателей событий. Я думаю, у вас есть такой код в вашем render
:
<button onClick={this.validateEmail} />
на рекомендуемое решение для React-привязать обработчики событий в вашем конструкторе:
class Something extends React.Component {
constructor() {
super();
this.validateEmail = this.validateEmail.bind(this);
}
// ...
}
вы также можете вызвать метод изнутри функции стрелки, которая сохраняет значение this
на месте было объявлено:
<button onClick={() => this.validateEmail()} />
недостатком этого подхода является то, что новый onClick
обработчик создается каждый раз при визуализации компонента.
редактировать: та же проблема, другое место. Вы звоните removeStatus
внутри function
, который теряет внешний this
привязка. Вместо этого используйте функцию стрелки:
$.ajax({
success: (response) => {
// etc
this.removeStatus();
}
})
далее чтение:
у меня была аналогичная проблема
Я просто столкнулся с аналогичной проблемой с тем же сообщением об ошибке. Странно то, что иногда, когда я вызываю метод внутри другого метода, он работает. Я делаю игру Simon, и следующий метод в методе работает.
handleMouseDown (e) {
if(e.target.id==="green"){
$("#green").addClass("colorGreenPush");
greenSound.play();
clicked.push(1);
this.handleCheck();
}
Я просто запускаю метод проверки, когда пользователь нажимает кнопку. Никакая ошибка.
однако я получал TypeError с этим кодом
handleCheck () {
var display = $("#display");
if(litID.length == clicked.length){
if(litID.join() == clicked.join()){
if(round == 20){
setTimeout(function(){
alert("Unreal. You Acually Won!!!");
location.reload();
},1000);
}
else{
setTimeout(function(){
display.text("-"+(round + 1)+"-");
round ++;
console.log(this);
litID = [];
clicked = [];
j = 0;
this.handleGame();
},1000);
}
}
ближе к концу я попробовать this.handleGame();
и это не сработало.
Мое Решение
вы заметите, что я сделал console.log(this);
просто чтобы посмотреть, что это было в этот момент. Оказывается, это был объект Window. Я не знаю, почему, возможно, похоронен в заявлениях if/else. Оба метода связаны, так что проблема не в этом.
абы. Я пошарил в окне объекта и оказалось, что я могу использовать this.App.prototype.handleGame();
и это работает! Я должен добавить, что имя моего основного компонента ES6-приложение. Это будет отличаться на основе ваших имен компонентов и методов, но общий принцип все равно должен применяться.
Я В Шоке
Я признаю, что я новенькая. Это мой второй мини-проект в React, но найти это было самое крутое. Теперь могут быть другие способы, такие как функции стрелки, упомянутые выше, но это то, что сработало для меня. И это была разница между игрой и прямым мусором. Надеюсь, это поможет кто-то.