I try Qwik framework which looks a lot like Reactjs and uses jsx. And suddenly, I wonder if Reactjs libraries such as MUI can work with Qwik framework.
I tried this code:
import { component$ } from "#builder.io/qwik";
import Add from "#mui/icons-material/Add";
import IconButton from "#mui/material/IconButton";
const AddToCartButton = component$(() => {
return (
<IconButton>
<Add />
</IconButton>
);
});
export default AddToCartButton;
But I got this this error:
QWIK ERROR Code(25): Invalid JSXNode type. It must be either a function or a string. Found: {
'$$typeof': Symbol(react.memo),
type: {
'$$typeof': Symbol(react.forward_ref),
render: [Function: Component] { displayName: 'AddIcon', muiName: 'SvgIcon' }
},
compare: null
} Error: Code(25): Invalid JSXNode type. It must be either a function or a string. Found:
at logError (E:\qwik\flower\node_modules\#builder.io\qwik\core.cjs:4515:58)
at logErrorAndStop (E:\qwik\flower\node_modules\#builder.io\qwik\core.cjs:4521:21)
at qError (E:\qwik\flower\node_modules\#builder.io\qwik\core.cjs:4585:16)
at Proxy.jsx (E:\qwik\flower\node_modules\#builder.io\qwik\core.cjs:605:23)
at AddToCartButton_component_4S0nJgnxzBU (/src/addtocartbutton_component_4s0njgnxzbu.js:11:55)
at useInvoke (E:\qwik\flower\node_modules\#builder.io\qwik\core.cjs:149:30)
at E:\qwik\flower\node_modules\#builder.io\qwik\core.cjs:4676:32
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async renderSSR (E:\qwik\flower\node_modules\#builder.io\qwik\core.cjs:5280:9)
at async Proxy.renderToStream (E:\qwik\flower\node_modules\#builder.io\qwik\server.cjs:582:3)
at async file:///E:/qwik/flower/node_modules/#builder.io/qwik/optimizer.mjs:1776:30
QWIK ERROR Code(25): Invalid JSXNode type. It must be either a function or a string. Found: Error: Code(25): Invalid JSXNode type. It must be either a function or a string. Found:
at logError (E:\qwik\flower\node_modules\#builder.io\qwik\core.cjs:4515:58)
at logErrorAndStop (E:\qwik\flower\node_modules\#builder.io\qwik\core.cjs:4521:21)
at qError (E:\qwik\flower\node_modules\#builder.io\qwik\core.cjs:4585:16)
at Proxy.jsx (E:\qwik\flower\node_modules\#builder.io\qwik\core.cjs:605:23)
at AddToCartButton_component_4S0nJgnxzBU (/src/addtocartbutton_component_4s0njgnxzbu.js:11:55)
at useInvoke (E:\qwik\flower\node_modules\#builder.io\qwik\core.cjs:149:30)
at E:\qwik\flower\node_modules\#builder.io\qwik\core.cjs:4676:32
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async renderSSR (E:\qwik\flower\node_modules\#builder.io\qwik\core.cjs:5280:9)
at async Proxy.renderToStream (E:\qwik\flower\node_modules\#builder.io\qwik\server.cjs:582:3)
at async file:///E:/qwik/flower/node_modules/#builder.io/qwik/optimizer.mjs:1776:30
not rendered
JSX in this case is the templating language of Qwik but the underlyings are different. It is made similar so you have an easier transition from react as stated in their docs.
Qwik is familiar for React developers and can be used to build any type of web site or application.
Qwik offers some adapter for react components you need to install and wrap your components in.
npm i -D #builder.io/qwik-react
And then the usage should look like the example in their repo.
/** #jsxImportSource react */
import { qwikify$ } from '#builder.io/qwik-react';
import { Button } from '#mui/material';
export const App = qwikify$(() => {
return (
<>
<Button variant="contained">Hola</Button>
</>
);
});
This thread is a bit older but maybe someone stumbles across it like me.
I had the same issue using a UI-component library and resolved it with the following steps.
adding qwikReact into the vite.config file:
import { defineConfig } from "vite";
import { qwikVite } from "#builder.io/qwik/optimizer";
import { qwikCity } from "#builder.io/qwik-city/vite";
import { qwikReact } from "#builder.io/qwik-react";
import tsconfigPaths from "vite-tsconfig-paths";
export default defineConfig(() => {
return {
plugins: [qwikCity(), qwikVite(), qwikReact(), tsconfigPaths()],
preview: {
headers: {
"Cache-Control": "public, max-age=600",
},
},
};
});
qwikify() must be used in a seperate file only with /** #jsxImportSource react */ as Jonathan pointed out.
Be aware that react components will not be treated the same way in Qwik. As stated in the docs it should be a migration/testing tool for existing projects where react components should be introduced in "Wide islands".
For those of you who are using Qwik Speak for I18N, the proposed solution will not work as is because Qwik-Speak won't be able to handle the JSX. The solution is to individually wrap the MUI component and then use it normally as so:
import { component$ } from "#builder.io/qwik";
import { Link } from "#builder.io/qwik-city";
import { $translate as t, Speak } from "qwik-speak";
import Button from "#mui/material/Button";
import { qwikify$ } from "#builder.io/qwik-react";
export const MUIButton = qwikify$(Button);
export default component$(() => {
return (
<Speak assets={["welcome"]}>
<div>
<h1>{t("welcome.title##Welcome")}</h1>
<MUIButton variant="contained">Do Something</MUIButton>
</div>
</Speak>
);
})
Related
I want to write stories for both React and Svelte components. I already have a few React components, and I'm attempting to install Svelte. My closest attempt can either run React OR Svelte depending on whether I comment out my React configuration. If I don't comment it out, I get this message when I look at my Svelte component in storybook:
Error: Objects are not valid as a React child (found: object with keys {Component}). If you meant to render a collection of children, use an array instead.
in unboundStoryFn
in ErrorBoundary
(further stack trace)
This refers to my story stories/test.svelte-stories.js:
import { storiesOf } from '#storybook/svelte';
import TestSvelteComponent from '../src/testComponentGroup/TestSvelteComponent.svelte';
storiesOf('TestSvelteComponent', module)
.add('Svelte Test', () => ({
Component: TestSvelteComponent
}));
My configuration is as follows:
.storybook/config.js:
import './config.react'; // If I comment out this line, I can make the svelte component work in storybook, but of course my react stories won't appear.
import './config.svelte';
.storybook/config.react.js:
import { configure } from '#storybook/react';
const req = require.context('../stories', true, /\.react-stories\.js$/);
function loadStories() {
req.keys().forEach(filename => req(filename));
}
configure(loadStories, module);
.storybook/config.svelte.js:
import { configure } from '#storybook/svelte';
const req = require.context('../stories', true, /\.svelte-stories\.js$/);
function loadStories() {
req.keys().forEach(filename => req(filename));
}
configure(loadStories, module);
.storybook/webpack.config.js:
module.exports = async ({ config, mode }) => {
let j;
// Find svelteloader from the webpack config
const svelteloader = config.module.rules.find((r, i) => {
if (r.loader && r.loader.includes('svelte-loader')) {
j = i;
return true;
}
});
// safely inject preprocess into the config
config.module.rules[j] = {
...svelteloader,
options: {
...svelteloader.options,
}
}
// return the overridden config
return config;
}
src/testComponentGroup/TestSvelteComponent.svelte:
<h1>
Hello
</h1>
It seems as though it's attempting to parse JSX via the Svelte test files, but if I import both React AND Svelte configurations I can still see the React components behaving properly.
See this discussion on github : https://github.com/storybookjs/storybook/issues/3889
It's not possible now and it's planned for the v7.0
The official position now is to create two sets of configuration (preview and manager), instanciate two separates storybook, and then use composition to assemble the two storybook into one.
I have a project which is on react but files are not .js instead they are .tsx and I am trying to use stripe library but keep getting error.
I have tried few different libraries which help setting up stripe but I am keep getting stuck on this errr.
Please help or direct me to correct library which help me setup stripe.
my codes are
import ReactDOM from "react-dom";
import StripeCheckout from 'react-stripe-checkout';
import axios from "axios";
function handleToken(token, addresses) {
console.log(token, addresses);
}
export default function Webinar() {
return (
<div className="container">
<StripeCheckout stripeKey = "mykey"
token={handleToken}
name="Tesla Roadster"
billingAddress
shippingAddress
/>
</div>
);
}
The problem is saying that your Typescript repo is now strict mode enabled which forces you specify the typing. If you wish to keep it silent, you can simply switch it to false in tsconfig.json:
{
"compilerOptions": {
"strict": false,
// ...
}
}
Change your function handleToken to be a variable with has the same type of your component prop as following:
const handleToken: StripeCheckout['props']['token'] = (token) => {
// You can receive hint from token type here
}
I get this warring in my react app.
It says componentWillReceiveProps has been renamed...
But I don't have "componentWillReceiveProps" in my code only effects ...
Maybe it is inside in node modules.
So i trying to ignore them
But i don't know how...
I used create-react-app
And i am using ts-lint.
Largely inspired from this answer
const error = console.error;
function logError(...parameters) {
let filter = parameters.find(parameter => {
return (
// Filter error because XXX
parameter.includes("Warning: %s is deprecated in StrictMode")
// Another error to filter because of YYYY
|| parameter.includes("Warning:")
);
});
if(!filter) error(...parameters);
}
console.error = logError;
Note that this code only works for errors, but you can duplicate it for console.warn or info
You can manage this in a particular .js file, and import it in the App.js
By using below code you can hide the desirable warnings
import React from 'react';
import { YellowBox } from 'react-native';
import AppNavigator from './app/main';
YellowBox.ignoreWarnings([
'Warning: isMounted(...) is deprecated',
'Module RCTImageLoader',
'Class RCTCxxModule',
'Task orphaned for request ',
'Warning',
'Require',
'Missing field __typename in',
'Node',
]);
const App = () => <AppNavigator />;
export default App;
When I upgrade v4, I get errors:
Uncaught (in promise) Invariant Violation: You must pass a component to the function returned by connect. Instead received {"propTypes":{},"displayName":"WithStyles(EditDialog)",...}
I tried to view the version of react-redux according to the I'm getting error after upgrading to Material UI 4 - withStyles method:
$ npm view react-redux version
7.1.0
Obviously, our situation is different.
It should be noted that my project is written using class component, so maybe this is the reason?
Is there any way to help me locate the problem?
----- Apend --------------
I'm use umi framework, And this is my code:
account/index.js
import React from 'react';
import { connect } from 'dva';
import { withStyles } from '#material-ui/core';
import styles from '#/utils/pageLayout';
...
import DetailDialog from './components/DetailDialog';
import EditDialog from './components/EditDialog';
class Index extends React.Component {
...
}
function mapStateToProps(state) {
const { list } = state.account;
return {
list
};
}
export default connect(mapStateToProps)(withStyles(styles)(Index));
account/components/DetailDialog.js
import React from 'react';
import { connect } from 'dva';
import { withStyles } from '#material-ui/core';
import styles from '#/utils/pageLayout';
...
class DetailDialog extends React.Component {
...
}
DetailDialog.propTypes = {
open: PropTypes.bool,
...
};
function mapStateToProps(state) {
const { list } = state.account;
return {
list
};
}
export default connect(mapStateToProps)(withStyles(styles)(DetailDialog));
account/components/EditDialog.js
import React from 'react';
import { connect } from 'dva';
import { withStyles } from '#material-ui/core';
import styles from '#/utils/pageLayout';
...
class EditDialog extends React.Component {
...
}
EditDialog.propTypes = {
open: PropTypes.bool.isRequired,
};
EditDialog.defaultProps = {
open: false,
};
function mapStateToProps(state) {
const { list} = state.account;
return {
list,
};
}
export default connect(mapStateToProps)(withStyles(styles)(EditDialog));
#/utils/pageLayout.js
const styles = theme => ({
r: {
height: '100%',
},
...
});
export default styles;
I see that you are importing connect from 'dva'. Unless you are using a beta version, the latest version of dva is 2.4.1 which includes react-redux as a dependency (not a peer dependency) and it is using "react-redux": "5.0.7". This will then have the exact same problem as the question you linked to.
This means you probably have two versions of react-redux in play (and likely two versions of redux as well), one included directly in your own package.json and one pulled in by dva.
Your main options would be to upgrade dva to its most recent beta version (currently 2.6.0-beta.12) or import connect from react-redux instead of dva.
I don't know anything about dva, so I have no idea what shape the beta is in, but given that it is the 12th beta, I would guess it is pretty close to a stable release.
If you are consistently importing redux/react-redux pieces from dva, then you may want to consider removing react-redux and redux from your own package.json to avoid duplicating them with different versions.
I want to use marked in reactjs as described in the reactjs docs.
<div>{marked(mystring)}</div>
I use babel so I import marked like this:
import { marked } from 'marked';
Unfortunately the import statement does not work. marked is not defined.
How do I have to import marked here, so that I can use it?
Here's one way to use marked with React:
Ensure that you've installed marked
Include marked in your project's package.json file:
// package.json
{
dependencies: {
react: "^17.0.0",
marked: "^4.0.0",
},
}
Import marked in your .jsx (or related) file:
import { marked } from "marked";
Use the dangerouslySetInnerHTML approach as shown in the example below:
import React from "react";
import { marked } from "marked";
class MarkdownExample extends React.Component {
getMarkdownText() {
var rawMarkup = marked.parse("This is _Markdown_.");
return { __html: rawMarkup };
}
render() {
return <div dangerouslySetInnerHTML={this.getMarkdownText()} />;
}
}
The dangerouslySetInnerHTML attribute gives you the ability to work with raw (HTML) markup. Make sure to take care when using this attribute, though!
Alternative (Safe)
If you don't want to use dangerouslySetInnerHTML and safely render HTML. Try marked-react, which internally uses marked to render the html elements as react components
npm i marked-react
import Markdown from "marked-react";
const MarkdownComponent = () => {
return <Markdown>{rawmarkdown}</Markdown>;
};
Another alternative is react-markdown
Here is another way of using marked with React Hooks:
Create your MarkedConverter component
import { useState } from 'react'
import marked from 'marked'
export const MarkedConverter = () => {
const [markedVal, setMarkedVal] = useState(
'# Welcome to my React Markdown Previewer!'
)
return <div dangerouslySetInnerHTML={createMarkUp(markedVal)}></div>
}
Create Markup function and pass the value from MarkedConverter Component
export const createMarkUp = (val) => {
return { __html: marked(val) }
}
Finally you can import MarkedConverter Component to any of your Component
With the marked-wrapper react-marked-markdown:
import { MarkdownPreview } from 'react-marked-markdown'
export default ({ post }) => (
<div>
<h1>{ post.title }</h1>
<MarkdownPreview value={ post.content }/>
</div>
)
If you just want to import marked:
import marked from 'marked';
Then call the function in your component:
marked('# Markdown');
Here's an example on how to use marked with react:
Install marked with NPM : npm i marked
import it in your react app (this example is created with create-react-app), and using it
example of a react component using "marked"
result in the browser :
preview