Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Duplicate canvas when running in vite dev #272

Closed
Mo0812 opened this issue Sep 27, 2023 · 5 comments
Closed

Duplicate canvas when running in vite dev #272

Mo0812 opened this issue Sep 27, 2023 · 5 comments

Comments

@Mo0812
Copy link

Mo0812 commented Sep 27, 2023

Expected Behavior

As many ReactP5Wrapper instances as integrated

Actual Behavior

For each ReactP5Wrapper instance is two canvas are shown

Steps to Reproduce the Problem

  1. npm create vite@latest
  2. npm install @p5-wrapper/react
  3. App.js:
import { useState } from 'react'
import reactLogo from './assets/react.svg'
import viteLogo from '/vite.svg'
import './App.scss'
import { ReactP5Wrapper } from '@p5-wrapper/react'

function App() {
  const [count, setCount] = useState(0)

  function sketch(p5) {
    p5.setup = () => p5.createCanvas(600, 400);
  
    p5.draw = () => {
        if (p5.mouseIsPressed) {
            p5.fill(0);
          } else {
            p5.fill(255);
          }
          p5.ellipse(p5.mouseX, p5.mouseY, 80, 80);
    };
  }
  

  return (
    <>
      <div>
        <a href="https://vitejs.dev" target="_blank" rel="noreferrer">
          <img src={viteLogo} className="logo" alt="Vite logo" />
        </a>
        <a href="https://react.dev" target="_blank" rel="noreferrer">
          <img
            src={reactLogo}
            className="logo react"
            alt="React logo"
          />
        </a>
      </div>
      <h1>Vite + React</h1>
      <div className="card">
        <button onClick={() => setCount((count) => count + 1)}>
                    count is {count}
        </button>
        <p>
                    Edit <code>src/App.jsx</code> and save to test HMR
        </p>
      </div>
      <p className="read-the-docs">
                Click on the Vite and React logos to learn more
      </p>
      <ReactP5Wrapper sketch={sketch} />
    </>
  )
}

export default App

Specifications

Package Version: 4.2.0

@jamesrweb
Copy link
Collaborator

Is your react app using strict mode?
Are you using NextJS?

P5 binds to the element reference of the containing element, should that element ever change or the reference differ, a new canvas will be rendered. Reacts strict mode does this as part of its "double render test" strategy.

NextJS causes this since the element would be rendered once on the server and once on the client (in such a case you should be using the @P5-wrapper/next implementation instead to work around that specific use case.

@jamesrweb
Copy link
Collaborator

Also see #255, #162, etc

@Mo0812
Copy link
Author

Mo0812 commented Sep 28, 2023

Hey @jamesrweb,
thanks a lot for your answer. I am not using Next.js, but do use strict mode in react due to the default configuration of the vite@latest composition. By removing the strict mode tag I also get rid of the duplicate canvas.

@Mo0812 Mo0812 closed this as completed Sep 28, 2023
@jordiyapz
Copy link

This worked! Please add that workaround into the readme file to help others solving this common confusion :)

For me, I moved the ReactP5Wrapper outside of StrictMode wrapper like this:

// main.tsx
// ...

// Remove the `StrictMode` wrapper, leaving the `App` unwrapped.
ReactDOM.createRoot(document.getElementById("root")!).render(<App />);
// App.tsx
// ...

function App() {
  return (
    <>
      {/* The p5wrapper component is free from `StrictMode` */}
      <ReactP5Wrapper sketch={sketch} />
      <React.StrictMode>
        {/* While this area has strict mode enabled */}
        <p>Hello, strict mode!</p>
      </React.StrictMode>
    </>
  );
}

@jamesrweb
Copy link
Collaborator

This worked! Please add that workaround into the readme file to help others solving this common confusion :)

For me, I moved the ReactP5Wrapper outside of StrictMode wrapper like this:

// main.tsx

// ...



// Remove the `StrictMode` wrapper, leaving the `App` unwrapped.

ReactDOM.createRoot(document.getElementById("root")!).render(<App />);

// App.tsx

// ...



function App() {

  return (

    <>

      {/* The p5wrapper component is free from `StrictMode` */}

      <ReactP5Wrapper sketch={sketch} />

      <React.StrictMode>

        {/* While this area has strict mode enabled */}

        <p>Hello, strict mode!</p>

      </React.StrictMode>

    </>

  );

}

@jordiyapz would you be willing to submit a PR?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants