Javascript 如何在持久的NextJS React音频播放器组件中捕获Mobx可观察到的更新?

Javascript 如何在持久的NextJS React音频播放器组件中捕获Mobx可观察到的更新?,javascript,reactjs,next.js,mobx,server-side-rendering,Javascript,Reactjs,Next.js,Mobx,Server Side Rendering,我有一个服务器端渲染音频播放器应用程序 使用,我有一个持久的AudioPlayer组件,在其中,每当mobx存储中的@observable playerData={}发生变化时,我想调用一个内部this.play(mp3url)函数 我已经成功地在我的应用程序update playerData中的其他组件上点击了按钮(只要需要) 但是我无法在AudioPlayer组件中检测到这些更新,因此我可以设置其状态并调用this.play(mp3url)开始播放音频 pages/_app.js impor

我有一个服务器端渲染音频播放器应用程序

使用,我有一个持久的AudioPlayer组件,在其中,每当mobx存储中的
@observable playerData={}
发生变化时,我想调用一个内部
this.play(mp3url)
函数

我已经成功地在我的应用程序update playerData中的其他组件上点击了按钮(只要需要)

但是我无法在AudioPlayer组件中检测到这些更新,因此我可以设置其状态并调用
this.play(mp3url)
开始播放音频

pages/_app.js

import initializeStore from '../stores/stores';

export default class MyApp extends App {

  static async getInitialProps(appContext) {
    const mobxStore = initializeStore();
    appContext.ctx.mobxStore = mobxStore;
    const appProps = await App.getInitialProps(appContext);
    return {
      ...appProps,
      initialMobxState: mobxStore,
    };
  }

  constructor(props) {
    super(props);
    this.mobxStore = props.initialMobxState;
  }

  render () {
    const { Component, pageProps } = this.props
    return (
      <Provider {...this.mobxStore}>
          <Component {...pageProps} />
        { this.mobxStore.playerStore.playerActive && <AudioPlayer /> }
      </Provider>
    )
  }
}
import ReactPlayer from 'react-player'
import { inject, observer } from 'mobx-react'

@inject('playerStore')
@observer
class Player extends Component{
    constructor(props) {
        super(props)
        this.state = {
            url: null,
            image: null
        }
    }
    componentWillUpdate(nextProps) {
        this.setState({
            url: nextProps.playerStore.playerData.url,
            image: nextProps.playerStore.playerData.image
        }, () => { this.play(this.state.url) })
    }

    // ...Other react-player functions

    render() {
        <ReactPlayer 
        {/* ...required props... */}
        />
    }
}
从“../stores/stores”导入初始化存储;
导出默认类MyApp扩展应用程序{
静态异步getInitialProps(appContext){
const mobxStore=initializeStore();
appContext.ctx.mobxStore=mobxStore;
const-appProps=await-App.getInitialProps(appContext);
返回{
…appProps,
initialMobxState:mobxStore,
};
}
建造师(道具){
超级(道具);
this.mobxStore=props.initialMobxState;
}
渲染(){
const{Component,pageProps}=this.props
返回(
{this.mobxStore.playerStore.playerActive&}
)
}
}
组件/AudioPlayer.js

import initializeStore from '../stores/stores';

export default class MyApp extends App {

  static async getInitialProps(appContext) {
    const mobxStore = initializeStore();
    appContext.ctx.mobxStore = mobxStore;
    const appProps = await App.getInitialProps(appContext);
    return {
      ...appProps,
      initialMobxState: mobxStore,
    };
  }

  constructor(props) {
    super(props);
    this.mobxStore = props.initialMobxState;
  }

  render () {
    const { Component, pageProps } = this.props
    return (
      <Provider {...this.mobxStore}>
          <Component {...pageProps} />
        { this.mobxStore.playerStore.playerActive && <AudioPlayer /> }
      </Provider>
    )
  }
}
import ReactPlayer from 'react-player'
import { inject, observer } from 'mobx-react'

@inject('playerStore')
@observer
class Player extends Component{
    constructor(props) {
        super(props)
        this.state = {
            url: null,
            image: null
        }
    }
    componentWillUpdate(nextProps) {
        this.setState({
            url: nextProps.playerStore.playerData.url,
            image: nextProps.playerStore.playerData.image
        }, () => { this.play(this.state.url) })
    }

    // ...Other react-player functions

    render() {
        <ReactPlayer 
        {/* ...required props... */}
        />
    }
}
从“react player”导入react player
从“mobx react”导入{inject,observer}
@注入('playerStore')
@观察者
类播放器扩展组件{
建造师(道具){
超级(道具)
此.state={
url:null,
图像:空
}
}
组件将更新(下一步){
这是我的国家({
url:nextrops.playerStore.playerData.url,
image:nextrops.playerStore.playerData.image
},()=>{this.play(this.state.url)})
}
//…其他玩家功能
render(){
}
}
那么,如何让这个持久性音频播放器检测音频中的变化呢 mobx可观察到播放音频URL


到目前为止,
componentWillReceiveProps
componentWillUpdate
componentdiddupdate
不会被调用<当我设置
@observable playerActive=true

设法找到它时,code>componentDidMount会像预期的那样被调用一次。这是由两个问题引起的

  • 根据Mobx文件
  • 观察器函数/装饰器可用于将ReactJS组件转换为reactive组件。它将组件的渲染函数包装在mobx.autorun中,以确保组件渲染期间使用的任何数据在发生更改时强制重新渲染。可通过单独的mobx react软件包获得

    需要在observer组件的渲染函数中使用store observable,以便组件对其更改做出反应。所以我在AudioPlayer组件中添加了它们,而不是从它自己的状态中获取它们

  • 我在
    pages/_app.js
    构造函数中遗漏了这一关键代码行,该构造函数本可以在客户端正确初始化mobx存储
    现在,AudioPlayer组件对mobx可观察到的每个更新做出反应,我能够处理
    组件WillUpdate
    /
    组件DidUpdate

    中进一步需要的逻辑,非常感谢您的示例。我有一个关于音乐的工作网站,我想把它变成React。为了保持我的搜索引擎优化优势,我将React路由器的测试切换到了NextJS。但我绝对需要那个音频播放器永远不要停在页面上。如果需要帮助,我会检查并联系你。是的,我检查过了,一旦我将播放器放入
    \u app.js
    ,NextJS将永远无法摆脱它。因此,我在
    \u app.js
    上使用带有事件的功能道具来随时更新播放器