How to use react setState with chrome API

谁说胖子不能爱 提交于 2021-02-09 14:47:08

问题


I want to use react's setState with chrome API but I'm running into an issue...

componentDidMount() {

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

I tried the following but chrome API does not recognize setState as a function, so then I tried to first save request.source as a variable...

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

But when I try the following, source remains an empty string. I cannot figure out why since source is being set to request.source. How can I fix this?

EDIT

I am calling a script as so...

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

and inside the script I have the following...

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

Where DOMtoString function simply returns a string. It is the caught by my componentDidMount which I have verified by printing to the console inside the if statement.

It has come to my attention that the addListener is asynchronous. Is there any way I can save the result in the state?


回答1:


You need to bind this so it is unchanged in the event listener

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

Your second attempt doesn't work because the callback is asynchronous. You need to call setState when the callback returns. In your second attempt, you register for the listener but then immediately call setState.

Edit: Alternatively, you could switch to using arrow functions instead. This would lexically bind this so it would be unchanged.

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


来源:https://stackoverflow.com/questions/40512815/how-to-use-react-setstate-with-chrome-api

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!