NextJs中同一页面用PythonProvider与usePython导致状态不更新的问题
在Next.js中使用react-py时,同页面使用PythonProvider和usePython导致sendInput失效的问题
我在Next.js应用里用react-py调用pyodide,这个库要求用PythonProvider包裹使用Python的组件。但在同一个客户端页面同时使用PythonProvider和usePython钩子时,sendInput功能失效。调试发现PythonProvider里输入相关的值已经变化,但usePython(封装PythonContext的钩子)未同步更新。将PythonProvider移到layout.js后功能恢复正常,想问下是否存在ContextProvider与useContext不能在同一页面使用的限制?
状态不更新的page.js代码
'use client' import { useState, useEffect } from 'react' import { PythonProvider, usePython } from '../../react-py/src' const Page = () => { const [code, setCode] = useState('input("hello:")') const { interruptExecution, isAwaitingInput, isLoading, isReady, isRunning, prompt, runPython, sendInput, stderr, stdout } = usePython() useEffect(() => { navigator.serviceWorker .register('/service-worker.js') .then((registration) => console.log( 'Service Worker registration successful with scope: ', registration.scope ) ) .catch((err) => console.log('Service Worker registration failed: ', err)) }, []) return ( <PythonProvider> {isAwaitingInput && <p>INPUT A</p>} {isLoading && <p>Loading A</p>} {isReady && <p>READY A</p>} {isRunning && <p>RUNNING A</p>} <input type="text" value={code} onChange={e=>setCode(e.target.value)}/> <button onClick={e=>{runPython(code)}}>RUN</button> <button onClick={e=>{sendInput('sdfghj')}}>SEND INPUT</button> <button onClick={e=>{interruptExecution()}}>INTERUPT</button> <p>{stdout}</p> </PythonProvider> ) } export default Page
可正常运行的代码
layout.js
'use client' import { Inter } from "next/font/google"; import "./globals.css"; import { useEffect } from "react"; import { PythonProvider } from "../../react-py/src"; const inter = Inter({ subsets: ["latin"] }); export default function RootLayout({ children }) { useEffect(() => { navigator.serviceWorker .register('/service-worker.js') .then((registration) => console.log( 'Service Worker registration successful with scope: ', registration.scope ) ) .catch((err) => console.log('Service Worker registration failed: ', err)) }, []) return ( <html lang="en"> <PythonProvider> <body className={inter.className}>{children}</body> </PythonProvider> </html> ); }
page.js
'use client' import { useState, useEffect } from 'react' import { usePython } from '../../react-py/src' const Page = () => { const [code, setCode] = useState('input("hello:")') const { interruptExecution, isAwaitingInput, isLoading, isReady, isRunning, prompt, runPython, sendInput, stderr, stdout } = usePython() return ( <> {isAwaitingInput && <p>INPUT A</p>} {isLoading && <p>Loading A</p>} {isReady && <p>READY A</p>} {isRunning && <p>RUNNING A</p>} <input type="text" value={code} onChange={e=>setCode(e.target.value)}/> <button onClick={e=>{runPython(code)}}>RUN</button> <button onClick={e=>{sendInput('sdfghj')}}>SEND INPUT</button> <button onClick={e=>{interruptExecution()}}>INTERUPT</button> <p>{stdout}</p> </> ) } export default Page
内容的提问来源于stack exchange,提问作者XotEmBotZ
相关产品推荐
相关产品推荐

