app.js 如何更新react-jinke-music-player 里面的播放列表
How to update playlist of react-jinke-music-player inside in app.js
我正在使用 react-jinke-music-player 播放 mp3 文件。如果我的 mp3 列表和播放器在同一页面上,它工作正常。
如果我更改另一个页面,音乐播放器将停止。符合预期。
因此,我使用 React.createContext()
在 app.js
的应用级别添加播放器,如下所示。
我认为全局变量已更新,但 play 的播放列表未更新。
请问如何更新不在同一页面的播放器的播放列表。
app_context.js
import React from 'react';
const AppContext = React.createContext();
export default AppContext;
app.js
import React, { useState } from 'react';
import { Toaster } from 'react-hot-toast';
import Header from './components/header';
import SideMenu from './components/side_menu';
import AppRoutes from './routes';
import { AuthProvider } from './auth/auth_provider';
import withUser from './hocs/with_user';
import ReactJkMusicPlayer from 'react-jinke-music-player';
import 'react-jinke-music-player/assets/index.css';
import options from '../src/constants/autio_player';
import AppContext from './components/app_context';
function App(props) {
const [playerOptions, setPlayerOptions] = useState(options);
const [sideBarFull] = useState(true);
const userSettings = {
playerOptions,
setPlayerOptions,
};
const PageHeader = () => {
return (
<div
className="h-[72px] w-full flex items-center align-middle justify-center
bg-neutral shadow"
>
<div className="w-full text-center">
<Header />
</div>
</div>
);
};
return (
<AuthProvider user={props.user}>
<AppContext.Provider value={userSettings}>
<div className="relative w-full min-h-screen min-w-[480px] h-full">
<div className="flex flex-row min-h-screen">
<div className="w-auto z-0 ">
<div className="flex-1 w-full max-h-screen mx-auto text-lg h-full shadow-lg bg-white overflow-y-auto">
<SideMenu showFullMenu={sideBarFull} />
</div>
</div>
<div className="w-full max-h-screen flex flex-col z-10">
<PageHeader />
<div className="flex-1 w-full max-h-screen mx-auto text-lg h-full shadow-lg bg-white overflow-y-auto">
<Toaster />
<AppRoutes />
<ReactJkMusicPlayer {...playerOptions} />
</div>
</div>
</div>
</div>
</AppContext.Provider>
</AuthProvider>
);
}
export default withUser(App);
playlist.js
const myContext = useContext(AppContext);
options.audioLists = playlist;
myContext.setPlayerOptions(options);
在您的 App
组件中,您正在创建状态,该状态使用 const [playerOptions, setOptions] = useState(options)
保存玩家的选项
options
是你的 initialOptions
(你也可以这样命名)。
接下来,您将 options
和 setOptions
作为值传递给您的 AppContext.Provider
。然后选项和 setter 可以被其他组件使用。
您可以将以下代码片段放在单独的模块中并导出 AppContext
和提供程序。 (在下面的代码和 Codesandbox 中,所有内容都在一个文件中。)
另外创建一个 useAppContext
或 usePlayerContext
挂钩可能会很有趣,如果你有很多地方都在使用它。
const AppContext = createContext({
options,
setOptions: () => {}
});
<AppContext.Provider value={{options: playerOptions, setOptions}}>
<SideMenu/>
</AppContext.Provider>
此处的“特殊性”是您在使用 App
组件的任何地方都使用了 setOptions
引用。
所以它正在改变你的应用程序的状态。
现在,在 SideMenu
组件中,您可以使用 const {options, setOptions} = useContext(AppContext)
获取上下文并使用 setOptions
方法更改选项。
请小心保留其他选项并始终将它们合并为:setOptions({...options, audioLists: newAudiolist})
(否则您可能会在不注意的情况下意外丢失一些选项)
您可以选择添加检查上下文是否定义为
const context = useContext(AppContext)
if (context === undefined) {
throw new Error("AppContext was used outside of its Provider");
}
演示代码:
抱歉,下面的代码片段在这里不起作用,但您可以在 Codesandbox 上查看。
const { useState, createContext, useContext } = React;
//import ReactJkMusicPlayer from "react-jinke-music-player";
//import "./styles.css";
//import "react-jinke-music-player/assets/index.css";
const audioList1 = [
{
name: "Despacito",
singer: "Luis Fonsi",
cover:
"http://res.cloudinary.com/alick/image/upload/v1502689731/Despacito_uvolhp.jpg",
musicSrc:
"http://res.cloudinary.com/alick/video/upload/v1502689683/Luis_Fonsi_-_Despacito_ft._Daddy_Yankee_uyvqw9.mp3"
// support async fetch music src. eg.
// musicSrc: async () => {
// return await fetch('/api')
// },
},
{
name: "Dorost Nemisham",
singer: "Sirvan Khosravi",
cover:
"https://res.cloudinary.com/ehsanahmadi/image/upload/v1573758778/Sirvan-Khosravi-Dorost-Nemisham_glicks.jpg",
musicSrc:
"https://res.cloudinary.com/ehsanahmadi/video/upload/v1573550770/Sirvan-Khosravi-Dorost-Nemisham-128_kb8urq.mp3"
}
];
const audioList2 = [
{
name: "Bedtime Stories",
singer: "Jay Chou",
cover:
"http://res.cloudinary.com/alick/image/upload/v1502375978/bedtime_stories_bywggz.jpg",
musicSrc:
"http://res.cloudinary.com/alick/video/upload/v1502375674/Bedtime_Stories.mp3"
}
];
const audioList3 = [
{
name: "Despacito",
singer: "Luis Fonsi",
cover:
"http://res.cloudinary.com/alick/image/upload/v1502689731/Despacito_uvolhp.jpg",
musicSrc:
"http://res.cloudinary.com/alick/video/upload/v1502689683/Luis_Fonsi_-_Despacito_ft._Daddy_Yankee_uyvqw9.mp3"
},
{
name: "Bedtime Stories",
singer: "Jay Chou",
cover:
"http://res.cloudinary.com/alick/image/upload/v1502375978/bedtime_stories_bywggz.jpg",
musicSrc:
"http://res.cloudinary.com/alick/video/upload/v1502375674/Bedtime_Stories.mp3"
},
{
name: "Dorost Nemisham",
singer: "Sirvan Khosravi",
cover:
"https://res.cloudinary.com/ehsanahmadi/image/upload/v1573758778/Sirvan-Khosravi-Dorost-Nemisham_glicks.jpg",
musicSrc:
"https://res.cloudinary.com/ehsanahmadi/video/upload/v1573550770/Sirvan-Khosravi-Dorost-Nemisham-128_kb8urq.mp3"
}
];
const options = {
audioLists: audioList1,
clearPriorAudioLists: true
};
const SideMenu = () => {
const { options, setOptions } = useContext(AppContext);
// nit check if Sidemenu is inside AppContext - omitted here
return (
<div style={{ marginTop: "100px" }}>
<h2>SideMenu</h2>
<button
onClick={() => setOptions({ ...options, audioLists: audioList1 })}>
Playlist1
</button>
<button
onClick={() => setOptions({ ...options, audioLists: audioList2 })}>
Playlist2
</button>
<button
onClick={() => setOptions({ ...options, audioLists: audioList3 })}>
Playlist3
</button>
</div>
);
};
const AppContext = createContext({
options,
setOptions: () => {}
});
function App(props) {
const [playerOptions, setPlayerOptions] = useState(options);
const [sideBarFull] = useState(true);
const userSettings = {
playerOptions,
setPlayerOptions
};
/*const PageHeader = () => {
return (
<div className="h-[72px] w-full flex items-center align-middle justify-center
bg-neutral shadow">
<div className="w-full text-center">
<Header />
</div>
</div>
);
};*/
return (
<AppContext.Provider
value={{ options: playerOptions, setOptions: setPlayerOptions }}
>
<div className="relative w-full min-h-screen min-w-[480px] h-full">
<div className="flex flex-row min-h-screen">
<div className="w-auto z-0 ">
<div className="flex-1 w-full max-h-screen mx-auto text-lg h-full shadow-lg bg-white overflow-y-auto">
<SideMenu showFullMenu={sideBarFull} />
</div>
</div>
<div className="w-full max-h-screen flex flex-col z-10">
{/*<PageHeader />*/}
<div className="flex-1 w-full max-h-screen mx-auto text-lg h-full shadow-lg bg-white overflow-y-auto">
{/*<AppRoutes />*/}
<ReactJkMusicPlayer {...playerOptions} />
</div>
</div>
</div>
</div>
</AppContext.Provider>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(
<App />,
rootElement
);
<script src="https://cdn.jsdelivr.net/npm/react-jinke-music-player@4.24.2/lib/index.min.js"></script>
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/react-jinke-music-player@4.24.2/assets/index.css">
<div id="root"></div>
我正在使用 react-jinke-music-player 播放 mp3 文件。如果我的 mp3 列表和播放器在同一页面上,它工作正常。 如果我更改另一个页面,音乐播放器将停止。符合预期。
因此,我使用 React.createContext()
在 app.js
的应用级别添加播放器,如下所示。
我认为全局变量已更新,但 play 的播放列表未更新。
请问如何更新不在同一页面的播放器的播放列表。
app_context.js
import React from 'react';
const AppContext = React.createContext();
export default AppContext;
app.js
import React, { useState } from 'react';
import { Toaster } from 'react-hot-toast';
import Header from './components/header';
import SideMenu from './components/side_menu';
import AppRoutes from './routes';
import { AuthProvider } from './auth/auth_provider';
import withUser from './hocs/with_user';
import ReactJkMusicPlayer from 'react-jinke-music-player';
import 'react-jinke-music-player/assets/index.css';
import options from '../src/constants/autio_player';
import AppContext from './components/app_context';
function App(props) {
const [playerOptions, setPlayerOptions] = useState(options);
const [sideBarFull] = useState(true);
const userSettings = {
playerOptions,
setPlayerOptions,
};
const PageHeader = () => {
return (
<div
className="h-[72px] w-full flex items-center align-middle justify-center
bg-neutral shadow"
>
<div className="w-full text-center">
<Header />
</div>
</div>
);
};
return (
<AuthProvider user={props.user}>
<AppContext.Provider value={userSettings}>
<div className="relative w-full min-h-screen min-w-[480px] h-full">
<div className="flex flex-row min-h-screen">
<div className="w-auto z-0 ">
<div className="flex-1 w-full max-h-screen mx-auto text-lg h-full shadow-lg bg-white overflow-y-auto">
<SideMenu showFullMenu={sideBarFull} />
</div>
</div>
<div className="w-full max-h-screen flex flex-col z-10">
<PageHeader />
<div className="flex-1 w-full max-h-screen mx-auto text-lg h-full shadow-lg bg-white overflow-y-auto">
<Toaster />
<AppRoutes />
<ReactJkMusicPlayer {...playerOptions} />
</div>
</div>
</div>
</div>
</AppContext.Provider>
</AuthProvider>
);
}
export default withUser(App);
playlist.js
const myContext = useContext(AppContext);
options.audioLists = playlist;
myContext.setPlayerOptions(options);
在您的 App
组件中,您正在创建状态,该状态使用 const [playerOptions, setOptions] = useState(options)
options
是你的 initialOptions
(你也可以这样命名)。
接下来,您将 options
和 setOptions
作为值传递给您的 AppContext.Provider
。然后选项和 setter 可以被其他组件使用。
您可以将以下代码片段放在单独的模块中并导出 AppContext
和提供程序。 (在下面的代码和 Codesandbox 中,所有内容都在一个文件中。)
另外创建一个 useAppContext
或 usePlayerContext
挂钩可能会很有趣,如果你有很多地方都在使用它。
const AppContext = createContext({
options,
setOptions: () => {}
});
<AppContext.Provider value={{options: playerOptions, setOptions}}>
<SideMenu/>
</AppContext.Provider>
此处的“特殊性”是您在使用 App
组件的任何地方都使用了 setOptions
引用。
所以它正在改变你的应用程序的状态。
现在,在 SideMenu
组件中,您可以使用 const {options, setOptions} = useContext(AppContext)
获取上下文并使用 setOptions
方法更改选项。
请小心保留其他选项并始终将它们合并为:setOptions({...options, audioLists: newAudiolist})
(否则您可能会在不注意的情况下意外丢失一些选项)
您可以选择添加检查上下文是否定义为
const context = useContext(AppContext)
if (context === undefined) {
throw new Error("AppContext was used outside of its Provider");
}
演示代码:
抱歉,下面的代码片段在这里不起作用,但您可以在 Codesandbox 上查看。
const { useState, createContext, useContext } = React;
//import ReactJkMusicPlayer from "react-jinke-music-player";
//import "./styles.css";
//import "react-jinke-music-player/assets/index.css";
const audioList1 = [
{
name: "Despacito",
singer: "Luis Fonsi",
cover:
"http://res.cloudinary.com/alick/image/upload/v1502689731/Despacito_uvolhp.jpg",
musicSrc:
"http://res.cloudinary.com/alick/video/upload/v1502689683/Luis_Fonsi_-_Despacito_ft._Daddy_Yankee_uyvqw9.mp3"
// support async fetch music src. eg.
// musicSrc: async () => {
// return await fetch('/api')
// },
},
{
name: "Dorost Nemisham",
singer: "Sirvan Khosravi",
cover:
"https://res.cloudinary.com/ehsanahmadi/image/upload/v1573758778/Sirvan-Khosravi-Dorost-Nemisham_glicks.jpg",
musicSrc:
"https://res.cloudinary.com/ehsanahmadi/video/upload/v1573550770/Sirvan-Khosravi-Dorost-Nemisham-128_kb8urq.mp3"
}
];
const audioList2 = [
{
name: "Bedtime Stories",
singer: "Jay Chou",
cover:
"http://res.cloudinary.com/alick/image/upload/v1502375978/bedtime_stories_bywggz.jpg",
musicSrc:
"http://res.cloudinary.com/alick/video/upload/v1502375674/Bedtime_Stories.mp3"
}
];
const audioList3 = [
{
name: "Despacito",
singer: "Luis Fonsi",
cover:
"http://res.cloudinary.com/alick/image/upload/v1502689731/Despacito_uvolhp.jpg",
musicSrc:
"http://res.cloudinary.com/alick/video/upload/v1502689683/Luis_Fonsi_-_Despacito_ft._Daddy_Yankee_uyvqw9.mp3"
},
{
name: "Bedtime Stories",
singer: "Jay Chou",
cover:
"http://res.cloudinary.com/alick/image/upload/v1502375978/bedtime_stories_bywggz.jpg",
musicSrc:
"http://res.cloudinary.com/alick/video/upload/v1502375674/Bedtime_Stories.mp3"
},
{
name: "Dorost Nemisham",
singer: "Sirvan Khosravi",
cover:
"https://res.cloudinary.com/ehsanahmadi/image/upload/v1573758778/Sirvan-Khosravi-Dorost-Nemisham_glicks.jpg",
musicSrc:
"https://res.cloudinary.com/ehsanahmadi/video/upload/v1573550770/Sirvan-Khosravi-Dorost-Nemisham-128_kb8urq.mp3"
}
];
const options = {
audioLists: audioList1,
clearPriorAudioLists: true
};
const SideMenu = () => {
const { options, setOptions } = useContext(AppContext);
// nit check if Sidemenu is inside AppContext - omitted here
return (
<div style={{ marginTop: "100px" }}>
<h2>SideMenu</h2>
<button
onClick={() => setOptions({ ...options, audioLists: audioList1 })}>
Playlist1
</button>
<button
onClick={() => setOptions({ ...options, audioLists: audioList2 })}>
Playlist2
</button>
<button
onClick={() => setOptions({ ...options, audioLists: audioList3 })}>
Playlist3
</button>
</div>
);
};
const AppContext = createContext({
options,
setOptions: () => {}
});
function App(props) {
const [playerOptions, setPlayerOptions] = useState(options);
const [sideBarFull] = useState(true);
const userSettings = {
playerOptions,
setPlayerOptions
};
/*const PageHeader = () => {
return (
<div className="h-[72px] w-full flex items-center align-middle justify-center
bg-neutral shadow">
<div className="w-full text-center">
<Header />
</div>
</div>
);
};*/
return (
<AppContext.Provider
value={{ options: playerOptions, setOptions: setPlayerOptions }}
>
<div className="relative w-full min-h-screen min-w-[480px] h-full">
<div className="flex flex-row min-h-screen">
<div className="w-auto z-0 ">
<div className="flex-1 w-full max-h-screen mx-auto text-lg h-full shadow-lg bg-white overflow-y-auto">
<SideMenu showFullMenu={sideBarFull} />
</div>
</div>
<div className="w-full max-h-screen flex flex-col z-10">
{/*<PageHeader />*/}
<div className="flex-1 w-full max-h-screen mx-auto text-lg h-full shadow-lg bg-white overflow-y-auto">
{/*<AppRoutes />*/}
<ReactJkMusicPlayer {...playerOptions} />
</div>
</div>
</div>
</div>
</AppContext.Provider>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(
<App />,
rootElement
);
<script src="https://cdn.jsdelivr.net/npm/react-jinke-music-player@4.24.2/lib/index.min.js"></script>
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/react-jinke-music-player@4.24.2/assets/index.css">
<div id="root"></div>