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

Use in a React project? #1

Closed
hadim opened this issue Oct 5, 2018 · 11 comments
Closed

Use in a React project? #1

hadim opened this issue Oct 5, 2018 · 11 comments
Labels
help wanted Extra attention is needed question Further information is requested

Comments

@hadim
Copy link

hadim commented Oct 5, 2018

How hard would it be to use this lib in a React project? I found a lot of examples to use React components into Preact projects but the other way...

@yishn
Copy link
Member

yishn commented Oct 5, 2018

I haven't tested it at all, but in theory, I've kept everything as compatible as possible to React. It should be as easy as aliasing the preact module to react in your favorite bundler. Maybe you can try it out?

@yishn yishn added question Further information is requested help wanted Extra attention is needed labels Oct 5, 2018
@hadim
Copy link
Author

hadim commented Oct 5, 2018

Ok. I'll try that. Thanks.

@mberd
Copy link

mberd commented Nov 2, 2018

@hadim this is how you can do it, it's a React wrapper for preact component

credit goes to this author https://swizec.com/blog/seamlessly-render-preact-component-react-project/swizec/8224

/** @jsx h */
import React from 'react';
import Preact, {h} from 'preact'

import { Goban } from '@sabaki/shudan'

export default class GobanWrapper extends React.Component {
    constructor(props) {
        super(props);

        let boardSize = props.boardSize ? props.boardSize : 19
        let vertexSize = props.vertexSize ? props.vertexSize : 19
        this.state = { 
            boardSize: boardSize,
            vertexSize: vertexSize, 
            signMap: props.signMap ? props.signMap : this.generateBoardSignMap(19) 
        };
    }

    componentDidMount() {
        this.renderPreact()
    }

    componentDidUpdate() {
        this.renderPreact
    }

    renderPreact() {
        Preact.render(
            <Goban vertexSize={this.state.vertexSize} signMap={this.state.signMap} />, 
            this.refs.goban
        )
    }

    generateBoardSignMap(size) {
        const x = new Array(size);
        for (let i = 0; i < size; i++) {
            x[i] = new Array(size);
            for (var j = 0; j < size; j++) {
                x[i][j] = 0;
            }
        }

        return x;
    };

    resetBoard() {
        this.setState({boardSize: this.state.newSize })
    };  

    render() {
        let h = React.createElement
        return <div ref="goban"></div>
    }
}

@yishn
Copy link
Member

yishn commented Nov 2, 2018

@mberd I don't think it's necessary to create a wrapper like that. In doing so, you'll need to bundle Preact as well as React in your webapp which is a little too much. Does it not work if you alias preact as react in webpack? If not, we should investigate and get it fixed.

@mberd
Copy link

mberd commented Nov 2, 2018

@yishn first - big thanks for writing this :)

this is the error i am getting

Warning: The component appears to have a render method, but doesn't extend React.Component. This is likely to cause errors. Change Goban to extend React.Component instead.

and I don't know/couldn't find how to use alias in webpack... :(

@mberd
Copy link

mberd commented Nov 2, 2018

fixed
in webpack.config.js:

resolve: {
    alias: {
      preact: "react"
    },
    extensions: ['*', '.js', '.jsx']
  },

now only this warning:

Warning: Unsafe legacy lifecycles will not be called for components using new component APIs.

Goban uses getDerivedStateFromProps() but also contains the following legacy lifecycles:
componentWillReceiveProps

The above lifecycles should be removed. Learn more about this warning here:
https://fb.me/react-async-component-lifecycle-hooks

@yishn
Copy link
Member

yishn commented Nov 2, 2018

Exactly, you have to alias preact as react. You can safely ignore the warning, since componentWillReceiveProps() is there for compatibility reasons with Preact. I guess everything works with React then? I'll close this issue, then.

@yishn yishn closed this as completed Nov 2, 2018
@psygo
Copy link

psygo commented Nov 21, 2023

I'm trying to make this work on NextJS but haven't been able to so far. Does anyone have a tip?

The core of the issue I'm having I believe is this:

Error: Class constructor Goban cannot be invoked without 'new'

This is apparently because Preact didn't use new to instantiate components but newer versions of React require it? Some solutions recommend using target: "es6" in your tsconfig.json to circumvent it, but I'm already doing that...

I'm having to use a // @ts-ignore because otherwise this is what I get:

'Goban' cannot be used as a JSX component.
  Its type 'ComponentClass<GobanProps, {}>' is not a valid JSX element type.
    Type 'ComponentClass<GobanProps, {}>' is not assignable to type 'new (props: any, deprecatedLegacyContext?: any) => Component<any, any, any>'.
      Property 'refs' is missing in type 'Component<GobanProps, {}>' but required in type 'Component<any, any, any>'.ts(2786)
index.d.ts(543, 9): 'refs' is declared here.

Here's what I have on my page.tsx:

// import { h } from "preact";
import { Goban } from "@sabaki/shudan";

export function CustomComponent() {
  return (
    // @ts-ignore
    <Goban
      vertexSize={24}
      signMap={[
        [0, 0],
        [0, 0],
      ]}
    />
  );
}

export default function Home() {
  return (
    <>
      <CustomComponent />
    </>
  );
}

My next.config.js:

/** @type {import('next').NextConfig} */
const nextConfig = {
  webpack: {
    resolve: {
      alias: {
        preact: "react",
        "preact/hooks": "react", // I have tried it with or without this line
      },
      extensions: ["*", ".js", ".jsx", ".ts", ".tsx"],
    },
  },
};

module.exports = nextConfig;

I'm using NextJS 14, here are the key dependencies on my package.json:

{
    "@sabaki/shudan": "^1.7.1",
    "next": "14.0.2",
    "preact": "^10.19.2",
}

@psygo
Copy link

psygo commented Jan 13, 2024

Here's an first attempt (I've actually tried many variations of it already): @psygo/embed_shudan

If anyone manages to get a template going, I would greatly appreciate it.

@andrew-taylor-2
Copy link

I got it working with vite in my vite.config.js with

export default defineConfig({
plugins: [react()],
resolve: {
alias: {
'preact/hooks': 'react',
preact: 'react',
},
extensions: ['*', '.js', '.jsx', '.ts', '.tsx']
}
});

I think the order of those aliases matters. Let the record reflect I'm not very knowledgeable about JS at all.

@psygo
Copy link

psygo commented Aug 4, 2024

@andrew-taylor-2 could you maybe share a template repo?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed question Further information is requested
Development

No branches or pull requests

5 participants