从外部触发时无法更新 React 组件状态
Can't update React Component state when triggered from outside
我对 React 比较陌生,还没有在网上找到解决方案。
我的代码:
const socketPlay = () => {
socket.emit("playing", true);
}
const socketStop = () => {
socket.emit("playing", false);
}
class App extends Component {
state = {
playing: false,
url: 'XXXX',
}
handlePlay = () => {
this.setState({ playing: true });
socketPlay();
}
handlePause = () => {
this.setState({ playing: false })
socketStop();
}
ref = player => {
this.player = player
}
render() {
const { url, playing, controls, light, volume, muted, loop, played, loaded, duration, playbackRate, pip } = this.state
const SEPARATOR = ' · '
return (
<ReactPlayer
ref={this.ref}
className='react-player'
width='40%'
playing={playing}
onPlay={this.handlePlay}
onPause={this.handlePause}
/>
)
}
}
export default App;
const app = new App();
socket.on("toClient", (args) => {
console.log("from server: " + args);
switch (args) {
case true:
app.handlePlay();
break;
case false:
app.handlePause();
break;
default:
break;
}
});
当我通过浏览器 handlePlay() 与组件交互时,正确设置了状态“playing: true”。如果通过 app.handlePlay() 在组件外部调用它,则状态保持为“正在播放:false”。
app.handlePlay() 得到正确执行。只有 this.setState 不工作。浏览器控制台抛出“警告:无法在尚未安装的组件上调用 setState。”
非常感谢您的帮助。
提前致谢,
一月
查看您的代码,在我看来,使用 componentDidMount
[=14= 在 App
Class 中添加 socket.on("toClient",
侦听器会更容易]
class App extends Component {
state = {
playing: false,
url: 'XXXX',
}
componentDidMount(){
socket.on("toClient", (args) => {
console.log("from server: " + args);
switch (args) {
case true:
this.handlePlay();
break;
case false:
this.handlePause();
break;
default:
break;
}
});
}
handlePlay = () => {
this.setState({ playing: true });
socketPlay();
}
handlePause = () => {
this.setState({ playing: false })
socketStop();
}
ref = player => {
this.player = player
}
render() {
const { url, playing, controls, light, volume, muted, loop, played, loaded, duration, playbackRate, pip } = this.state
const SEPARATOR = ' · '
return (
<ReactPlayer
ref={this.ref}
className='react-player'
width='40%'
playing={playing}
onPlay={this.handlePlay}
onPause={this.handlePause}
/>
)
}
}
export default App;
我对 React 比较陌生,还没有在网上找到解决方案。 我的代码:
const socketPlay = () => {
socket.emit("playing", true);
}
const socketStop = () => {
socket.emit("playing", false);
}
class App extends Component {
state = {
playing: false,
url: 'XXXX',
}
handlePlay = () => {
this.setState({ playing: true });
socketPlay();
}
handlePause = () => {
this.setState({ playing: false })
socketStop();
}
ref = player => {
this.player = player
}
render() {
const { url, playing, controls, light, volume, muted, loop, played, loaded, duration, playbackRate, pip } = this.state
const SEPARATOR = ' · '
return (
<ReactPlayer
ref={this.ref}
className='react-player'
width='40%'
playing={playing}
onPlay={this.handlePlay}
onPause={this.handlePause}
/>
)
}
}
export default App;
const app = new App();
socket.on("toClient", (args) => {
console.log("from server: " + args);
switch (args) {
case true:
app.handlePlay();
break;
case false:
app.handlePause();
break;
default:
break;
}
});
当我通过浏览器 handlePlay() 与组件交互时,正确设置了状态“playing: true”。如果通过 app.handlePlay() 在组件外部调用它,则状态保持为“正在播放:false”。
app.handlePlay() 得到正确执行。只有 this.setState 不工作。浏览器控制台抛出“警告:无法在尚未安装的组件上调用 setState。”
非常感谢您的帮助。 提前致谢, 一月
查看您的代码,在我看来,使用 componentDidMount
[=14= 在 App
Class 中添加 socket.on("toClient",
侦听器会更容易]
class App extends Component {
state = {
playing: false,
url: 'XXXX',
}
componentDidMount(){
socket.on("toClient", (args) => {
console.log("from server: " + args);
switch (args) {
case true:
this.handlePlay();
break;
case false:
this.handlePause();
break;
default:
break;
}
});
}
handlePlay = () => {
this.setState({ playing: true });
socketPlay();
}
handlePause = () => {
this.setState({ playing: false })
socketStop();
}
ref = player => {
this.player = player
}
render() {
const { url, playing, controls, light, volume, muted, loop, played, loaded, duration, playbackRate, pip } = this.state
const SEPARATOR = ' · '
return (
<ReactPlayer
ref={this.ref}
className='react-player'
width='40%'
playing={playing}
onPlay={this.handlePlay}
onPause={this.handlePause}
/>
)
}
}
export default App;