Closed hadim closed 5 years ago
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?
Ok. I'll try that. Thanks.
@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>
}
}
@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.
@yishn first - big thanks for writing this :)
this is the error i am getting
Warning: The
and I don't know/couldn't find how to use alias in webpack... :(
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
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.
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",
}
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.
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.
@andrew-taylor-2 could you maybe share a template repo?
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...