2014-10-13 2 views
11

Я пытаюсь получить доступ к состоянию компоненты внутри setInterval таким образом, но это не работает:Проблемы доступ состояния внутри setInterval в React.js

componentDidMount: function() { 
    setInterval(function() { 
     console.log(this.state); 
    }, 3000); 
} 

Однако, если поместить функцию обратного вызова в отдельный компонент, он отлично работает:

displayState: function() { 
    console.log(this.state) 
} 
componentDidMount: function() { 
    setInterval(this.displayState(), 3000); 
} 

Любая идея, почему это происходит? Я бы предпочел использовать первый вариант.

+0

Вторая версия работает, потому что React [ "авто-зываетс"] (HTTPS : //facebook.github.io/react/blog/2013/07/02/react-v0-4-autobind-by-default.html) методы на компонентах. Чтобы первая работа работала, «свяжите» функцию, как указано в одном из ответов. –

+2

вы не можете вызвать функцию при переходе на setInterval, которая сразу же запускает ее один раз, а интервал ничего не делает. как это работает отлично, я не получаю. – dandavis

ответ

22

В вашем первом примере this не работает, когда срабатывает функция обратного вызова. Одним из способов решения этой проблемы были бы использовать переменный:

componentDidMount: function() { 
    var self = this; 
    setInterval(function() { 
     console.log(self.state); 
    }, 3000); 
} 

Проблемы с вашей второй попыткой является то, что вы сразу же вызвать функцию и передавая результата выполнения функции в setInterval. Вы должны передать саму функцию, заботясь, чтобы связать значение this:

componentDidMount: function() { 
    setInterval(this.displayState.bind(this), 3000); 
} 

Чтобы прояснить различие между этим подходом и во втором примере в вашем вопросе является то, что здесь, функция в настоящее время передается setInterval (потому что function.bind() возвращает функцию).

При использовании React.createClass, вам не нужно самостоятельно связывать this, из-за autobind. Это означает, что вы можете просто передать функции себя и this будет таким же, как и в оригинальном контексте:

componentDidMount: function() { 
    setInterval(this.displayState, 3000); 
} 

Конечно, наиболее подходящий подход зависит от того, предпочитаете ли вы использовать анонимную функцию или нет.

+0

более чистый способ сделать это при повторном использовании фактического предполагаемого метода: \t componentDidMount: function() { \t \t setInterval (this.displayState.bind (this), 3000); \t}, ... (DRY) – dandavis

+0

@Tom Fenech В чем разница между этим и моим вторым примером? Он работает без 'bind'. –

+1

разница не имеет повторного кода (console.log) или дополнительной функции анона.если вы используете дополнительный анон, тогда вам не нужен bind(), вы можете использовать старый тэг «that = this»: componentDidMount: function() {var that = this; setInterval (function() {console.log (that.state);}, 3000); } – dandavis

4

Вам необходимо выполнить обработчик интервалов с правильной ссылкой на this. Использование РЕАКТ автоматическое связывание для cleasest решения IMO:

displayState: function() { 
    console.log(this.state) 
}, 
componentDidMount: function() { 
    setInterval(this.displayState, 3000) 
} 

Или использовать bind если вы хотите анонимную функцию:

componentDidMount: function() { 
    setInterval(function() { 
     console.log(this.state) 
    }.bind(this), 3000) 
} 
Смежные вопросы