admin管理员组文章数量:1410682
I have a backend app that constantly serves events to my React app via Web Sockets. When a specific event is received a new browser tab should be opened. The application will be run by a user in multiple tabs, so I need to open a new tab only once and prevent it from being opened by all running instances.
I've tried using Redux persistent storage, but it doesn't seem to correspond my needs. The best solution that I've found is Shared Workers.
I've tried using Shared Worker in my React app, but I can't set up it properly. It's either being imported incorrectly or Webpack is unable to load it
Uncaught SyntaxError: Unexpected token <
When I googled I haven't found any examples of using Shared Worker in React app (with or without CRA) and at this point, I'm not even sure it's possible. I did found some Web Workers examples, but they have totally different configs.
Can anyone please share some specifics of running Shared Worker in React? Or any other ideas that can provide me with similar functionality will be also greatly appreciated.
Edit: Adding lastest code of what I've tried. Disregard the counter logic, consider just the setup:
worker.js
import React from 'react';
export const startCounter = () => {
window.self.addEventListener("message", event => {
console.log(event.data, self);
let initial = event.data;
setInterval(() => this.postMessage(initial++), 1000);});
}
App.js
import React, { Component } from 'react';
import {startCounter} from './worker';
class App extends Component {
ponentDidMount() {
const worker = new SharedWorker(startCounter);
worker.port.start()
// worker.postMessage(this.state.counter);
// worker.addEventListener('message', event => this.setState({counter: event.data}));
}
render() {
return (
<div className="App">
</div>
);
}
}
export default App;
I have a backend app that constantly serves events to my React app via Web Sockets. When a specific event is received a new browser tab should be opened. The application will be run by a user in multiple tabs, so I need to open a new tab only once and prevent it from being opened by all running instances.
I've tried using Redux persistent storage, but it doesn't seem to correspond my needs. The best solution that I've found is Shared Workers.
I've tried using Shared Worker in my React app, but I can't set up it properly. It's either being imported incorrectly or Webpack is unable to load it
Uncaught SyntaxError: Unexpected token <
When I googled I haven't found any examples of using Shared Worker in React app (with or without CRA) and at this point, I'm not even sure it's possible. I did found some Web Workers examples, but they have totally different configs.
Can anyone please share some specifics of running Shared Worker in React? Or any other ideas that can provide me with similar functionality will be also greatly appreciated.
Edit: Adding lastest code of what I've tried. Disregard the counter logic, consider just the setup:
worker.js
import React from 'react';
export const startCounter = () => {
window.self.addEventListener("message", event => {
console.log(event.data, self);
let initial = event.data;
setInterval(() => this.postMessage(initial++), 1000);});
}
App.js
import React, { Component } from 'react';
import {startCounter} from './worker';
class App extends Component {
ponentDidMount() {
const worker = new SharedWorker(startCounter);
worker.port.start()
// worker.postMessage(this.state.counter);
// worker.addEventListener('message', event => this.setState({counter: event.data}));
}
render() {
return (
<div className="App">
</div>
);
}
}
export default App;
Share
Improve this question
edited Aug 31, 2018 at 21:54
Hisagr
asked Aug 31, 2018 at 20:44
HisagrHisagr
6216 silver badges13 bronze badges
6
-
Unexpected token <
usually means that you set up the path wrong, and the worker gets a 404 html page instead of a script – Bergi Commented Aug 31, 2018 at 20:50 - There's the issue with Webpack in CRA (github./facebook/create-react-app/issues/3660) Besides that, I'm not sure how worker.js should look like (the one that is passed to SharedWorker() constructor). In all old examples its immediately invoked function (function () {} ()) and I doubt this is the way to go in React. – Hisagr Commented Aug 31, 2018 at 20:58
-
Usually this happens when you do not import
React
in a file where you try to usejsx
. – trixn Commented Aug 31, 2018 at 20:59 - added some code – Hisagr Commented Aug 31, 2018 at 21:09
-
There is the opening class bracket missing after
Component
. – trixn Commented Aug 31, 2018 at 21:51
3 Answers
Reset to default 2make a file called WebWorker.js which looks like this:
export default class WebWorker {
constructor(worker) {
const code = worker.toString();
const blob = new Blob(['('+code+')()']);
return new SharedWorker(URL.createObjectURL(blob));
}
}
and import it to your main file and do this:
const workers = new WebWorker(worker);
workers.postMessage(some message);
Clarifying @Birat's answer: The SharedWorker constructor is looking for a URL, but here you're passing it a function:
const worker = new SharedWorker(startCounter);
Give this a try instead:
const worker = new SharedWorker(new URL('./worker', import.meta.url));
I migrated from CRA to Vite for my React App and I had to add type: 'module'
when instanciating the SharedWorker
:
Before:
new SharedWorker(new URL('./worker.ts', import.meta.url), {
name: 'Worker Name',
});
After
new SharedWorker(new URL('./worker.ts', import.meta.url), {
type: 'module',
name: 'Worker Name',
});
this solved my issue with the worker not being available during development
From Docs: https://v3.vitejs.dev/guide/features.html#web-workers
本文标签: javascriptUsing Shared Worker in ReactStack Overflow
版权声明:本文标题:javascript - Using Shared Worker in React - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744786073a2625008.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论