Importing p5 package into a React functional component?

Viewed 469

I'm trying to integrate p5.js into my React app.

There is an example showing how to do so here: https://dev.to/christiankastner/integrating-p5-js-with-react-i0d

class App extends React.Component {
  constructor(props) {
    super(props)
    this.myRef = React.createRef()
  }

  Sketch = (p) => {

     p.setup = () => {
     ...
     }

     p.draw = () => {
     ...
     }
  }

  componentDidMount() {
    this.myP5 = new p5(this.Sketch, this.myRef.current)
  }

  render() {
    return (
      <div ref={this.myRef}>

      </div>
    )
  }
}

But the example given is a Class component.

How can convert the above example into a functional component?

I tried the following:

import React, { useRef } from "react";
import p5 from "p5";

const App = () => {
  const processingRef = useRef();

  const Sketch = p => {
    p.setup = () => {};

    p.draw = () => {};
  };

  const newp5 = new p5(Sketch, processingRef);

  return <div ref={processingRef} />;
};

export default App;

but i was thrown the error on line const newp5 = new p5(Sketch, processingRef):

this._userNode.appendChild is not a function
2 Answers
import React, { useRef, useEffect } from "react";
import p5 from "p5";

const App = () => {
  const processingRef = useRef();
  const Sketch = p => {
    p.setup = () => {};

    p.draw = () => {};
     };
   useEffect(() => {
    const newp5 = new p5(Sketch, processingRef.current);
    }, [])

  return <div ref={processingRef} />;
};

export default App;

Passing no dependency in the useEffect hook makes it run once just like the componentDidMount Live Cycle Method

You should wait for the ref to be set first:

import React, { useRef } from "react";
import p5 from "p5";

const App = () => {
  const setProcessingRef = (element) => {
    if (element) {
      const Sketch = (p) => {
        p.setup = () => {};

        p.draw = () => {};
      };

      const newp5 = new p5(Sketch, processingRef);
    }
  };

  return <div ref={setProcessingRef} />;
};

export default App;

Related