How to work with class npm packages in react - javascript

so suppose I have an npm package I'd like to use with my project, which was not necessarily made for React. This particular package comes as a Class, which I need to make an object out of.
How could I achieve this in React, when working with class components? Is there a 'standardized way' of doing such a thing?
pseudocode:
import React, { Component } from "react";
import {whatever} from 'coolPackage'
class myReactClass extends Component {
myObject = new whatever()
render() {
return <div></div>;
}
}
export default myReactClass;

Ok, me noob, sorry all for waste time.
There is a problem with the npm package I was trying to use. After checking the error logs again, this time with a lot more care, the problem is not related to the question asked.

Related

Cannot resolve “node:http” when using libp2p with create-react-app

I am new to libp2p, so please excuse me if this is something that’s been asked/discussed elsewhere. I am trying to set up in a newly created project made with create-react-app. The app currently has one component with the following:
import React, {Component} from 'react';
import mplex from 'libp2p-mplex';
import Noise from 'libp2p-noise';
import Libp2p from 'libp2p';
class Connector extends Component {
constructor (props)
{
super(props);
this.state = {};
}
componentDidMount(){
node = Libp2p.create({
addresses:{
isten: [
'/dns4/wrtc-star1.par.dwebops.pub/tcp/443/wss/p2p-webrtc-star',
'/dns4/wrtc-star2.sjc.dwebops.pub/tcp/443/wss/p2p-webrtc-star'
]
},
modules:{
connEncryption:[Noise],
streamMuxer:[mplex],
transport:[WebSockets]
}
})
console.log(node);
}
render(){
return (<div>The connector component</div>);
}
}
export default Connector;
I know this alone is not enough to connect to anything, but it doesn’t even compile. I get the following error message when I run this:
Module not found: Can’t resolve ‘node:http’ in ‘/Users/myuser/projects/p2p-browser/node_modules/node-fetch/src’
I looked into the source code of the node-fetch module referenced and found that, indeed, it is requiring node:http. I also found that the node: prefix is to get node to include always node’s native http module. Since this is a react-app, which runs on the browser, I see no reason at all to use node-fetch, which leads me to think that either libp2p is not compatible with the browser, or somehow I am using the node.js version of libp2p instead of the “browser version”, though so far, I haven’t found any documentation to suggest there is a “browser version”, the examples I’ve seen use parcel and include the same npm modules. So, am I missing something, or is libp2p simply incompatible with create-react-app and needs to be compiled for the browser with parceljs?
Any help will be greatly appreciated. Thank you.

React Hooks Error: Hooks can only be called inside the body of a function component

I am getting this error when using the useState hook. I have this in it's basic form, looking at the react docs for a reference, but am still getting this error. I'm ready for the face palm moment...
export function Header() {
const [count, setCount] = useState(0)
return <span>header</span>
}
Updated: 2018-Dec
New version of react-hot-loader is out now, link. Hooks is now working out of the box. Thank to the author, theKashey.
Check out this boilerplate https://github.com/ReeganExE/react-hooks-boilerplate
React Hooks
React Hot Loader
Webpack, Babel, ESLint Airbnb
Previous Answer:
First, make sure you installed react#next and react-dom#next.
Then check for you are using react-hot-loader or not.
In my case, disable hot loader & HMR could get it work.
See https://github.com/gaearon/react-hot-loader/issues/1088.
Quoted:
Yes. RHL is 100% not compatible with hooks. There is just a few
reasons behind it:
SFC are being converted to Class components. There is reason - to be
able to forceUpdate on HMR, as long there is no "update" method on
SFC. I am looking for other way of forcing the update (like this. So
RHL is killing SFC.
"hotReplacementRender". RHL is trying to do React's job, and render
the old and the new app, to merge them. So, obviously, that's broken
now.
I am going to draft a PR, to mitigate both problems. It will work, but
not today.
There is a more proper fix, which would work - cold API
You may disable RHL for any custom type.
import { cold } from 'react-hot-loader';
cold(MyComponent);
Search for "useState/useEffect" inside component source code, and "cold" it.
Updated:
As per updated from react-hot-loader maintainer, you could try react-hot-loader#next and set the config as bellow:
import { setConfig } from 'react-hot-loader';
setConfig({
// set this flag to support SFC if patch is not landed
pureSFC: true
});
Thank to #loganfromlogan for the update.
My problem was forgetting to update react-dom module. See issue.
Had the same issue. My problem was related to React Router. I had accidentally used
<Route render={ComponentUsingHooks} />
instead of
<Route component={ComponentUsingHooks} />
I was able to solve this by importing React's primitive hooks in the component file, then passing them into my custom hooks. For some reason, the error only occurs when I import the React hook (like useState) in my custom hook file.
I'm importing useState in my component file:
import React, {useState} from 'react'; // import useState
import {useCustomHook} from '../hooks/custom-hook'; // import custom hook
const initialState = {items: []};
export default function MyComponent(props) {
const [state, actions] = useCustomHook(initialState, {useState});
...
}
Then in my hook file:
// do not import useState here
export function useCustomHook(initialValue, {useState}) {
const [state, setState] = useState(initialValue || {items: []});
const actions = {
add: (item) => setState(currentState => {
const newItems = currentState.items.concat([item]);
return {
...currentState,
items: newItems,
};
}),
};
return [state, actions];
}
This method has improved the testability of my hooks because I don't need to mock React's library to provide the primitive hooks. Instead, we can pass in a mock useState hook right into the custom hook's function. I think this improves code quality, as your custom hooks now have no coupling with the React library, allowing for more natural functional programming and testing.
I experienced this error while using Parcel's Hot Module Replacement, and fixed by updating react-dom to it's alpha version:
yarn add react-dom#16.7.0-alpha.0
See this issue.
I had a problem in a monorepo, where a package docz used react#16.6.3 and the final output bundle had two react versions.
Issue on Github
Fixed it by removing the package 😅
Just to elaborate on #rista404's answer, including duplicate versions of react (and perhaps react-dom) will yield the same error depending on where you are using your hooks. Here are two examples...
An external dependency includes another version of react in its dependencies, likely by mistake as react should usually be a peer dependency. If npm doesn't automatically dedupe this version with your local version, you may see this error. This is what #rista404 was referring to.
You npm link a package that includes react in its devDependencies or dependencies. Now, for modules in this package, you may see errors if they pull a different version of react from the their local node_modules directory rather than the parent project's.
The latter can be fixed when bundling with webpack by using resolve.alias like so...
resolve: {
alias: {
'react': path.resolve(__dirname, 'node_modules/react'),
'react-dom': path.resolve(__dirname, 'node_modules/react-dom')
}
}
This will ensure react is always pulled from the parent project's node_modules directory.
Another solution if you are running into this when using npm link:
You can npm link react in your library as explained here:
https://reactjs.org/warnings/invalid-hook-call-warning.html#duplicate-react
or set react in your library as peerDependency and then use npm link --only=production
The problem for me was indeed react-hot-loader.
You can disable react-hot-loader for a single component instead of the entire app using the cold method like this:
import { cold } from 'react-hot-loader'
export const YourComponent = cold(() => {
// ... hook code
return (
// ...
)
})
OR
export default cold(YourComponent)
My issue was the following:
I was doing:
ReactDOM.render(Example(), app);
Whereas I should have been doing:
ReactDOM.render(<Example />, app);
For those who come across this issue when using MobX and wrapping a component with an observer, make sure you use mobx-react-lite instead of mobx-react.
MAY 29 UPDATE
From mobx-react 6.0.0 onward, hook based components are now supported by mobx-react, thus, there is no need for mobx-react-lite usage anymore (if that was your problem).
JUNE 2021 ANSWER
I've been experiencing this problem with the react-electron-boilerplate app.
Many plugins and libraries like Material-UI couldn't be used in my project because of this unfortunate error and after searching a lot, I could solve the problem:
I just upgraded the react and react-dom to their latest versions.
This command got the job done!
yarn add react#latest react-dom#latest
found this workaround for react-hot-loader while that PR to fix it is inbound.
Wrap the function that calls hooks in a React.memo, preventing a hot reload if it's unchanged.
const MyFunc = React.memo(({props}) => {...
Credit for solution:
https://github.com/gatsbyjs/gatsby/issues/9489
For fellow users of yarn workspaces, here's my situation and how I figured it out.
packages
foo
react#16.8.6
bar
react#16.10.1
The Facebook docs on Invalid Hook Call Warning say nothing about yarn workspaces, so I assumed my config was correct. But it wasn't. You can fix the error only by using the same version across all your packages.
In the example above, you have to bump the version of react from "foo" to 16.10.1, so that it matches the react version from "bar".
Bonus: see this discussion on GitHub for a beautiful collection of emotional baggage offloaded on the Internet.
Well in my Case i was calling useSelector inside useEffect !!
If you are using Create React App, you have to update "react-scripts" version also with react and react-dom version.
"react-scripts": "2.1.5",
"react": "^16.8.1",
"react-dom": "^16.8.1",
this combination works fine.
For me, this was occurring because I had a new version of react (16.8.6) and an old version of react-dom (16.6.1).
https://reactjs.org/warnings/invalid-hook-call-warning.html#mismatching-versions-of-react-and-react-dom
Upgrading both to #latest (16.8.6) fixed the error.
Check react and react-dom versions are strictly equal. Take care of the circumflex ^ symbol on versions.
"17.0.0" could not be the same as "^17.0.0"
npm - Carret Ranges: https://github.com/npm/node-semver#caret-ranges-123-025-004
React - Changelog: https://github.com/facebook/react/blob/main/CHANGELOG.md
That's one of the reasons to better install packages with -E or --save-exact
npm install --save --save-exact <package#vesion>
update package.json react-dom version as react

Using React 14 component from React 16 App

We use a React component package which provides some reusable components such as Button, Form, TreeView etc... That package is developed on top of React 14.
We want to develop a new application using React 16 and utilize this component package because it provides a lot of look and feel stuff out of the box.
Our code looks like this.
import React, {Component} from 'react';
import PropTypes from 'prop-types';
import Button from 'reusable-components/button';
export default class MyComponent extends Component {
render() {
return <Button>{this.props.buttonCaption}</Button>;
}
}
MyComponent.propTypes = {
buttonCaption: PropTypes.string
};
With this code, when I open the page, I get an error saying TypeError: o.PropTypes is undefined in the browser console. I believe "o.PropTypes" is the obfuscated version of "React.PropTypes" and I am getting this error because somewhere in the source code of Button component they used "React.PropTypes" which became invalid after React 14.
Another thing is that when I do not use Button and do not import it at all, everything works fine. So, I am pretty sure that the issue is caused by the Button component.
I tried below thing in my index.js but it did not help.
import React from 'react';
import PropTypes from 'prop-types';
React.PropTypes = PropTypes;
Is there a way to use React 14 components from React 16 app? In the worst case we will downgrade to 14 as the library does not have 16 support yet but we really want to avoid it.

How do I use Glimmer components inside an Ember app?

The Glimmer website states:
Just drop your Glimmer components into an Ember app. You won’t need to change a thing.
I’ve been following the official Ember quick start tutorial. I replaced the contents of the generated people-list.js component with this:
import Component from '#glimmer/component';
export default class PeopleList extends Component {
}
and I get an error in the browser console stating that #glimmer/component is undefined. After I run yarn add #glimmer/component to add the dependency, I get a new error from Broccoli.
Additionally, whenever I use '#' before a variable in the people-list.hbs template, the template fails to compile. How do I get the Glimmer component to work in my Ember app?
To use glimmer in an ember app today (May 1st, 2019),
yarn add --dev #glimmer/component#beta
then
import Component from '#glimmer/component';
import { tracked } from '#glimmer/tracking';
export default class MyComponent extends Component {
#tracked number = 0;
increment() {
this.number++;
}
}
to see this in action, take a look at a fresh Octane App: https://github.com/ember-cli/ember-octane-blueprint
Currently you can't use it for existing ember app. but you can try it brand new app. By installing ember new my-glimmer-app -b https://github.com/glimmerjs/glimmer-blueprint.git
If you go with yarn global add ember-cli/ember-cli this way then you need to uninstall existing ember-cli (npm uninstall -g ember-cli)

Import React vs React, { Component }

Import React vs Import React, { Component }
Which one is better and why?
Or does it make no difference other than writing less code later on?
Does writing { Component } mean it only imports the Component object?
import React, { Component } lets you do class Menu extends Component instead of class Menu extends React.Component. It's less typing and duplication of the React namespace, which is generally a desired modern coding convention.
Additionally, tools like Webpack 2 and Rollup do "tree shaking," meaning any unused exports are not bundled into your final code. With import React/React.Component you are guaranteeing all of React's source code will be bundled. With import { Component }, some tools will only bundle the code needed to use the Component class, excluding the rest of React.
The above paragraph is irrelevant in this specific case, because you always need to have React in the current namespace to write JSX, but only importing the exact modules you need in other cases may lead to smaller bundled code in the end.
Beyond that it's entirely personal preference.
What these are are named imports or namespace imports. What they do is basically copy over the module's contents into the namespace allowing:
import React, { Component } from 'react';
class SomeComponent extends Component { ... }
Normally, we'd extend React.Component, but since the Component module is imported into the namespace, we can just reference it with Component, React. is not needed. All React modules are imported, but the modules inside the curly brackets are imported in such a way that the React namespace prefix is not needed when accessing.
TLDR;
it's entirely personal preference.
Just a note…
import React, { Component } lets you do class Menu extends Component
instead of class Menu extends React.Component. It's less typing…
If you want to do less typing, then don't import Component in addition to React.
import React, { Component } from 'react';
class Menu from Component {
is more typing than:
import React form 'react';
class Menu from React.Component {
even if you consider auto-completion. ;)

Categories

Resources