2016-11-09 2 views
2

Я хочу использовать РЕАКТ setState с хромированной API, но я бегу на вопрос ...Как использовать реагировать SetState с хромированной API

componentDidMount() { 

    chrome.runtime.onMessage.addListener(function(request, sender) { 
     if (request.action == "getSource") { 
      this.setState({sourceCode: request.source}); 
     } 
    }); 
} 

Я попытался следующие, но хром API не распознает setState, как функция, поэтому я попытался сначала сохранить request.source как переменные ...

componentDidMount() { 
    var source = ""; 
    chrome.runtime.onMessage.addListener(function(request, sender) { 
     if (request.action == "getSource") { 
      source = request.source; 
     } 
    }); 
    this.setState({sourceCode: source}); 
} 

Но когда я пытаюсь следующим, source остается пустой строкой. Я не могу понять, почему с source устанавливается значение request.source. Как я могу это исправить?

EDIT

Я зову сценарий как так ...

chrome.tabs.executeScript(null, { 
     file: 'src/js/scripts/getPageSource.js' 
    }, function() { 
    ... 

и внутри сценария У меня есть следующие ...

chrome.runtime.sendMessage({ 
    action: "getSource", 
    source: DOMtoString(document) 
}); 

Где DOMtoString функция просто возвращает строку. Это поймано моим componentDidMount, которое я проверил, распечатав на консоли внутри оператора if.

Пришло к сведению, что addListener является асинхронным. Есть ли способ сохранить результат в состоянии?

+0

Пожалуйста, задавайте вопрос по теме: включите ** полный ** [mcve], который дублирует проблему. Включая * manifest.json *, некоторые из фоновых * и * скриптов содержимого. Вопросы, требующие помощи по отладке («** почему этот код не работает? **)) должны включать: ► желаемое поведение, ► конкретную проблему или ошибку * и * самый короткий код, необходимый для его воспроизведения ** в вопросе сам**. Вопросы без четкого описания проблемы не полезны другим читателям. Смотрите: «** Как создать [mcve] **», [о каких темах я могу спросить здесь?] (Http://stackoverflow.com/help/on-topic) и [ask]. – Makyen

+1

Знаете ли вы, что setState является асинхронным? Если вы хотите увидеть результат, вы должны запросить их внутри функции обратного вызова в setState(). т.е.: this.setState ({sourceCode: source}, function() {console.log (this.state.sourceCode)}) – Falk

+0

@Makyen внутри оператора 'if', если я' console.log' переменной 'source' , Я получаю правильный вывод. Но вне 'addListener',' source' остается пустая строка. Я не уверен, что еще вам нужно. – Bolboa

ответ

3

Вы должны связать this так неизменна в слушателе событий

chrome.runtime.onMessage.addListener(function(request, sender) { 
    if (request.action == "getSource") { 
     this.setState({sourceCode: request.source}); 
    } 
}.bind(this)); 

Ваша вторая попытка не работает, потому что обратный вызов асинхронной. Вам нужно позвонить setState, когда возвращается обратный вызов. Во второй попытке вы регистрируетесь для слушателя, но затем немедленно вызов setState.

Редактировать: Вместо этого вы можете переключиться на использование arrow functions. Это лексически связывает this, поэтому оно не изменится.

chrome.runtime.onMessage.addListener((request, sender) => { 
    if (request.action == "getSource") { 
     this.setState({sourceCode: request.source}); 
    } 
}); 
+3

Вы используете реакцию и JSX - проще использовать '=>' –

+0

Согласовано. Я бы добавил '=>' в качестве опции в ваш ответ. – azium

+1

Я предпочитал подход KISS, но добавил его в качестве опции. – AnilRedshift

Смежные вопросы