DEV Community

Discussion on: Python in React with Pyodide

Collapse
 
texas697 profile image
Rudy Sanchez

Thanks for the article. Having a issue. The Provider code isn't working for me. Didn't troubleshoot it too much. But trying to get the code to print out the result in the UI.

The correct answer 3+2 = 5 prints out in the console but is being returned as undefined here

"setPyodideOutput(await evaluatePython(pyodide.current, pythonCode));"

Any help would be great. Thank you

const pythonCode = 'print(3 + 2)';
const WasmPythonContainer = () => {
const classes = useStyles();
const indexURL = 'cdn.jsdelivr.net/pyodide/v0.19.1/f...';

const pyodide = React.useRef(null);
const hasLoadPyodideBeenCalled = React.useRef(false);
const [isPyodideLoading, setIsPyodideLoading] = React.useState(true);
const [pyodideOutput, setPyodideOutput] = React.useState('evaluating...');

// load pyodide wasm module and initialize it
React.useEffect(() => {
if (!hasLoadPyodideBeenCalled.current) {
// immediately set hasLoadPyodideBeenCalled ref, which is part of context, to true
// this prevents any additional Pyodide components from calling loadPyodide a second time
hasLoadPyodideBeenCalled.current = true;
(async function () {
pyodide.current = await window.loadPyodide({ indexURL });
// updating value of isPyodideLoading triggers second useEffect
setIsPyodideLoading(false);
})();
}
// pyodide and hasLoadPyodideBeenCalled are both refs and setIsPyodideLoading is a setState function (from context)
// as a result, these dependencies will be stable and never cause the component to re-render
}, [pyodide, hasLoadPyodideBeenCalled, setIsPyodideLoading]);

// evaluate python code with pyodide and set output
React.useEffect(() => {
if (!isPyodideLoading) {
const evaluatePython = async (pyodide: { runPython: (arg0: any) => any; }, pythonCode: string) => { // eslint-disable-line
try {
return pyodide.runPython(pythonCode);
} catch (error) {
console.error(error);
return 'Error evaluating Python code. See console for details.';
}
};
(async function () {
setPyodideOutput(await evaluatePython(pyodide.current, pythonCode));
})();
}
// component re-renders when isPyodideLoading changes, which is set with first useEffect and updated via context
}, [isPyodideLoading, pyodide, pythonCode]);

return (


Using WASM PYTHON


Pyodide Output: {isPyodideLoading ? 'loading...' : pyodideOutput}


);
};

export default WasmPythonContainer;