How to get class declarations from create-react-app? - reactjs

After creating a new react project using npx create-react-app new I'm getting functional js code in App.js:
import React from 'react';
import './App.css';
//need to have a class instead of a function here:
function App() {
return (
<div className="App">
</div>
);
}
export default App;
What command do I need to create a none functional react project? If functional is better than none functional please explain why.

If you have install create-react-app for this project, then it is come up with all the new features from react 16.8.6 (latest version of react). The latest react version come up with concept of Hooks. That is why we are getting functional component by default instead of class based component to increase the performance.
If you want class based component by default they you have to come up with older version of create-react-app. Ref

You can migrate react-scripts v3.x to v2.x like so:
npx create-react-app my-app --scripts-version react-scripts#2.1.7

When a new react app is created using create-react-app, it pulls the template from here https://github.com/facebook/create-react-app/tree/master/packages/react-scripts/template
Functional components are preferred than Class components (ES6 class) because, Functional components are usually stateless i.e. without any state and lifecycle methods - check this https://reactjs.org/docs/state-and-lifecycle.html. Their performance is better over class components which have state. Therefore, as a good practice one should always prefer as many stateless components (Functional) over stateful (Class), which is also done in react starter app i.e. create-react-app

Use: create-react-app <project> --scripts-version 2.1.7 to create a new react project that start with a class based App component rather than functional.

There are situations where a developer would prefer the class based design so the --scripts-version argument is good to know about.

Related

Adding React to a site; use of hooks/functional components

I am very new to react and need to rebuild two Angular.js components within a .NET Content Management System (Kentico). I do not believe there is an opportunity to run a react app/component through npm so I have gone the other route and "add React to a website" (https://reactjs.org/docs/add-react-to-a-website.html). I'm using browserify with babelify to compile my app/component code for the browser.
I've made some decent progress but believe I like the flexibility functional components bring to the table where I don't find coding within a class component all that familiar. Because I'm "adding React to a site" instead of running it through npm, I BELIEVE I have no opportunity to import hooks and thus: no opportunity for useState within functional components.
Can anyone verify this for me? That indeed, "adding react to a site" precludes one from using functional components: class components are the best I can do?
I guess it boils down to: I do not believe I can import useState/useEffect when I am "adding react to a site" in a way where react and react-dom are just script references at the base of my component.
Maybe someone can verify that for me or else point out how I would capitalize on functional components/hooks?
You can use hooks and classes freely no matter how you include them. It's not relevant. The old react docs only use classes which is confusing. Try beta docs: https://beta.reactjs.org/

Is there a way to import a react component without using 'import' statement

I'm new to React. Just trying out things.
So far I have been using CDNs for React, React-DOM, and React-Bootstrap. I had no trouble using components of React-Bootstrap using the example code below:
var Alert = ReactBootstrap.Alert;
Now my problem is I want to use a component that is not provided by React-Bootstrap so I tried to look for components available in Github. I found a lot of the components that I am looking for but all of them are available for installation via npm which I am avoiding since I'm using React thru CDN. I know it is recommended to use npm or create-react app, but that's not how I started my application.
So is there a way to import components like how I did in React-Bootstrap components? For example:
var Select = React.Select; // import Select from 'react-select';

React hooks in react library giving Invalid hook call error

I create a react library using https://www.npmjs.com/package/create-react-library
And successfully used it on other React project.
But when I tried to use react hooks functionalities inside library it gives me following error.
Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
.....
My Library
I just tried to use useState as follows in my component.
import React, { useState } from 'react'
const General = (props) => {
const [count, setCount] = useState(0);
return (
<div>
General component
</div>
)
}
export default General
I am using
"react": "^16.8.6" and "react-dom": "^16.8.6"
My React APP
Created a application using https://github.com/facebook/create-react-app and used above library as follows.
import Reactfrom 'react'
import { General } from 'my.lib'
const accountSummary = props => {
return (
<div>
<General>
</div>
)
}
export default accountSummary
Both has same react versions and library has used same react-dom and react versions as peerDependencies
I was including my component library (for that matter any library) in my application as #Janith did using my-comp-lib:"file:../.." (I don't want to publish every time I want to test) and I encountered the same issue.
Invalid hook call. Hooks can only be called inside of the body of a
function component. This could happen for one of the following
reasons:
You might have mismatching versions of React and the renderer (such as React DOM)
You might be breaking the Rules of Hooks
You might have more than one copy of React in the same app See react-invalid-hook-call for tips about how to debug and
fix this problem
I was able to fix this by making my app and library point to the same react (package) location.
Below are the steps I followed :
1. In Your Application:
a) cd node_modules/react && npm link
b) cd node_modules/react-dom && npm link
2. In Your Library
a) npm link react
b) npm link react-dom
3)Stop your dev-server and do `npm start` again.
It works!!
Please refer below links for more details ..
https://github.com/facebook/react/issues/14721
https://github.com/facebook/react/pull/14690
https://github.com/facebook/react/issues/13991
Note : This issue will not happen if you publish your package to artifactory and install because you will have react & react-dom as peer-dependencies and they won't get included in the distribution. So your package and application use the same react which is installed in the application.
I just ran into the same issue. I was able to fix it by pointing to the same react in my example app as in my library:
App Structure
Root
Example
package.json
src (library)
package.json
So, from the example > package.json I changed react to be:
"react": "link:../node_modules/react",
This is much like the npm link listed above but it won't go away every time you npm install.
I had the same issue, working with a rush monorepo, configuring ui-package and building the apps using nextjs.
The solutions was add the follow code on package.json
"resolutions": {
"react": "17.0.1", // verificate your react version
"react-dom": "17.0.1"
}
In the library's package.json:
"peerDependencies": {
"react": "17.0.1",
"react-dom": "17.0.1"
},
See more here: https://github.com/vercel/next.js/issues/9022#issuecomment-728688452
Add to your Components Library's package.json
"peerDependencies": {
"react": "<your version>"
}
so that your lib package will use the same react package as your main app.
https://nodejs.org/es/blog/npm/peer-dependencies/
It worked for me when I changed the link from the app to the library to be "link:../" instead of "file:../", in addition to linking react and react-dom.
React 17 + React Testing Library + Umi(a frontend framework, built-in react-router)
In my case, when I run the unit test, I got an error message "invalid hook call".
After a period of trying, I found two ways to solve.
Downgrade to React 16.x, then all will be fine.
Keep using React 17.x, and
Still have to write import React from 'react'
Install react-router-dom separately
I think it may be a problem with react-router, but due to my limited understanding, I don't have a better solution yet.
Also check your npm version. My version was 7.0.8 which was outdated, after changing it to 6.14.8 everything was working fine!
WHEN TESTING WITH REAL APP IN REACT NATIVE
I have same issue and i delete my node_module file in my custom library and i fixed it..
issue when installing direct module
yarn add c:/user......./react-native-some-lib
In my case I'm building my own common library. Although I was exporting createContext, useContext and useState from "react", I simply forgot to also import the default export, React.
Changing my import statement from this:
import { createContext, useContext, useState } from "react";
to this:
import React, { createContext, useContext, useState } from "react";
fixed it for me. You might have to do this in every React component/context etc that you are exporting from your react library.
Edit:
In another one of my apps that relies on this common library, this issue was also fixed using npm link as described in the React documentation (Invalid Hook Call Warning):
This problem can also come up when you use npm link or an equivalent. In that case, your bundler might “see” two Reacts — one in application folder and one in your library folder. Assuming myapp and mylib are sibling folders, one possible fix is to run npm link ../myapp/node_modules/react from mylib. This should make the library use the application’s React copy.
So in my case, I navigated to my common library and ran npm link ../path-to-my-app/node_modules/react.
Edit (23/02/2022)
Hopefully the final edit - another solution is to simply globally install the problem dependency if all apps expect to use the same version, e.g. npm install react -g
I have created a React library with create-react-library this library is your General component. I have published it to npm here https://www.npmjs.com/package/stackoverflow-test and a React app for use it here https://codesandbox.io/s/mm7yl83o28.
Just click on General component text and count will be incremented.
I cannot reproduce your issue, just use this test to check your implementation.

TypeScript and React issue

Well, recently I've started using the React.js library, and now I'm trying to use it with Firebase Hosting, with the TypeScript language. But, every time I try to write some code using tsx it just doesn't work, for example:
import * as React from "react"; //red underline under "react"
import "./App.css";
import logo from "./logo.svg";
class App extends React.Component {
render() {
return <h1>Hello</h1>; //red underline under <h1> and </h1>
}
}
export default App;
that way I just can't write any jsx code here, because it always appears the issue:
test.tsx(1,1): error TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists
Can somebody please help me with this?
How did you create your react application? If you used create-react-app you'll need to use react-scripts-ts as your --scripts-version flag. This should install the #types packages along side React's dependencies, eliminating your problem.
Also, it should get you started with an App.tsx file as the one provided in your snippet is not a valid typescript react component (i.e. the your render() method is not public).
Happy hacking!
I solved this issue by reloading VSCode.
ctrl+shift+P > Developer: Reload Window

React vs ReactDOM?

I'm a bit new to react. I see we have to import two things to get started, React and ReactDOM, can anyone explain the difference. I'm reading through the React documentation, but it doesn't say.
React and ReactDOM were only recently split into two different libraries. Prior to v0.14, all ReactDOM functionality was part of React. This may be a source of confusion, since any slightly dated documentation won't mention the React / ReactDOM distinction.
As the name implies, ReactDOM is the glue between React and the DOM. Often, you will only use it for one single thing: mounting with ReactDOM.render(). Another useful feature of ReactDOM is ReactDOM.findDOMNode() which you can use to gain direct access to a DOM element. (Something you should use sparingly in React apps, but it can be necessary.) If your app is "isomorphic", you would also use ReactDOM.renderToString() in your back-end code.
For everything else, there's React. You use React to define and create your elements, for lifecycle hooks, etc. i.e. the guts of a React application.
The reason React and ReactDOM were split into two libraries was due to the arrival of React Native. React contains functionality utilised in web and mobile apps. ReactDOM functionality is utilised only in web apps. [UPDATE: Upon further research, it's clear my ignorance of React Native is showing. Having the React package common to both web and mobile appears to be more of an aspiration than a reality right now. React Native is at present an entirely different package.]
See the blog post announcing the v0.14 release:
https://facebook.github.io/react/blog/2015/10/07/react-v0.14.html
From the React v0.14 Beta release announcement.
As we look at packages like react-native, react-art, react-canvas, and react-three, it's become clear that the beauty and essence of React has nothing to do with browsers or the DOM.
To make this more clear and to make it easier to build more environments that React can render to, we're splitting the main react package into two: react and react-dom.
Fundamentally, the idea of React has nothing to do with browsers, they just happen to be one of many targets for rendering trees of components into. The ReactDOM package has allowed the developers to remove any non-essential code from the React package and move it into a more appropriate repository.
The react package contains React.createElement, React.createClass and React.Component, React.PropTypes, React.Children, and the other helpers related to elements and component classes. We think of these as the isomorphic or universal helpers that you need to build components.
The react-dom package contains ReactDOM.render, ReactDOM.unmountComponentAtNode, and ReactDOM.findDOMNode, and in react-dom/server we have server-side rendering support with ReactDOMServer.renderToString and ReactDOMServer.renderToStaticMarkup.
These two paragraphs explain where the core API methods from v0.13 ended up.
TL;TR the react package is required to create and use components and hooks, react-dom contains react-dom/client and react-dom/server to render you app in the browser's DOM or inside a string (or a stream) on the server. With react-native you can use React to create native apps for Android and iOS.
This question has been asked almost seven years ago and a lot has changed since then.
Most of the answer are no longer correct or contains outdated information.
I'll try to give you a complete but simple answer with the most up to date information available.
React 18
In March 2022 React 18 has been released. It has brought some interesting changes in its public APIs.
Packages
react
As stated in React documentation:
React is the entry point to the React library. If you load React from a <script> tag, these top-level APIs are available on the React global.
Indeed it exposes most of the common React features to create and use components. Some of these are:
React.Component and React.PureComponent, used to create class components and function components
React.createElement(), used convert your JSX code from <Page title="Home page" />to React.createElement(Page, { title: "Home page" }, null)
React.Fragment, to return multiple elements without creating additional DOM elements (starting with React 16.2 you can also use <></> to create a fragment.
hooks, to let you use state and other React features without writing a class
Refs, Suspence and Transitions
Complete list of API exposed by the React object
react-dom, react-native and the others listed below are React renderers. They manage how a React tree turns into the underlying platform calls.
react-dom
The react-dom package provides DOM-specific methods that can be used at the top level of your app and as an escape hatch to get outside the React model if you need to.
This package is essentially a container used to expose both the client and server sub-packages from a single one. Indeed it exposes only two function:
createPortal(), used to create portals and render children outside the DOM hierarchy of the parent component
flushSync() is something you may not never have heard about and for a reason. Because it can significantly hurt performance.
Starting from React 18 these functions have been flagged as legacy, so they will be deprecated in future releases:
render()
hydrate()
findDOMNode()
unmountComponentAtNode()
If you are thinking "OMG they have deprecated the ´ReactDOM.render´ method from React", don't worry and read below.
The reason behind the deprecation is:
the opportunity to redesign the APIs we expose for rendering on the client and server. These changes allow users to continue using the old APIs in React 17 mode while they upgrade to the new APIs in React 18.
Keep in mind that if you continue to use those legacy APIs, new React 18 features will be disabled.
Complete list of API exposed by the react-dom package
react-dom/client
The react-dom/client package provides client-specific methods used for initializing an app on the client. Most of your components should not need to use this module.
The React DOM Client module exposes only two methods:
createRoot() is the new method to create a root where your app will. This the replacement for ReactDOM.render - see the example below
hydrateRoot() is the replacement for ReactDOM.hydrate, required to hydrate a server rendered application
Now the idiomatic way to render you app is using createRoot and render chained together:
import React from 'react';
import * as ReactDOM from 'react-dom/client';
ReactDOM
.createRoot(document.getElementById('root'))
.render(<h1>Hello, world!</h1>);
Or using a constant if you don't like chaining, it's just a matter of style:
import React from 'react';
import * as ReactDOM from 'react-dom/client';
const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(<h1>Hello, world!</h1>);
Complete list of API exposed by the react-dom/client package
react-dom/server
The ReactDOMServer object enables you to render components to static markup. Typically, it’s used on a Node server
Using ReactDOMServer you can render React components server-side. It offers a wide range of methods to achieve this - there are dedicated functions for every environment:
renderToPipeableStream(), uses Node.js Streams
renderToNodeStream() (Deprecated), uses Node.js Streams
renderToStaticNodeStream(), uses Node.js Streams
renderToReadableStream(), uses Web Streams available in browsers, Deno, ...
Moreover, there are also render that can be used in the environments that don not support streams:
renderToString() discouraged from React 18
renderToStaticMarkup()
You can use them but they have limited Suspense support.
This is a the minimal working example to try ReactDOMServer on your own:
import React from 'react';
import * as ReactDOMServer from 'react-dom/server';
const html = ReactDOMServer.renderToString(<h1>Hello, world!</h1>);
Complete list of API exposed by the react-dom/server package
react-native
With React Native, React primitives render to native platform UI, meaning your app uses the same native platform APIs other apps do.
React Native has now a huge ecosystem itself and it is not limited to only render components.
Today is no longer recommended to install the react-native module yourself. Instead, you can use the the expo-cli to take advantage of its automation for the development of your application.
Other React renderers
These are some of the most interesting renderer available today (not dead) for React
react-canvas
react-canvas project is dead, but similar features can be found in
react-konva. Using it you can render your React components inside an HTML canvas.
react-three
react-three has been superseded by react-three-fiber. It allows you to build your three.js scene declaratively from React.
ink
ink is a React renderer for CLIs. Using it you can build your CLI output using components.
react-figma
react-figma is a React renderer for Figma. You can use React components as a source for your designs.
react-pdf
react-pdf is a React renderer for creating PDF files on the browser and server.
FAQ
Where did prop-types go?
With the release of react 15.5 the prop-types library
moved outside of React into a dedicated package.
It looks like they've separated React into react and react-dom packages, so you don't have to use the DOM-related part for projects where you'd like to use it in non-DOM-specific cases, like in here https://github.com/Flipboard/react-canvas
where they import
var React = require('react');
var ReactCanvas = require('react-canvas');
as you can see. Without react-dom.
Before v0.14 they were part of main ReactJs file, but as in some cases we may not need both, they separate them and it starts from version 0.14, that way if we need only one of them, our app gonna be smaller due to using only one of those:
var React = require('react'); /* importing react */
var ReactDOM = require('react-dom'); /* importing react-dom */
var MyComponent = React.createClass({
render: function() {
return <div>Hello World</div>;
}
});
ReactDOM.render(<MyComponent />, node);
React package contains: React.createElement, React.createClass, React.Component, React.PropTypes, React.Children
React-dom package contains: ReactDOM.render, ReactDOM.unmountComponentAtNode, ReactDOM.findDOMNode, and react-dom/server that's including: ReactDOMServer.renderToString and ReactDOMServer.renderToStaticMarkup.
To be more concise, react is for the components and react-dom is for rendering the components in the DOM. 'react-dom' acts as a glue between components and DOM. You will be using render() method of the react-dom to render components in the DOM and that's all you have to know when you are starting off with it.
The ReactDOM module exposes DOM-specific methods, while React has the core tools intended to be shared by React on different platforms (e.g. React Native).
http://facebook.github.io/react/docs/tutorial.html
React: React is a javascript library, designed for building better user interfaces.
React-DOM: React-DOM is a complimentary library to React which glues React to the browser DOM
We’re using React and whenever we use methods like render() or findDOMNode() we’re using React-DOM.
As we look at packages like react-native, react-art, react-canvas, and react-three, it's become clear that the beauty and essence of React has nothing to do with browsers or the DOM.
To make this more clear and to make it easier to build more environments that React can render to, they splitting the main react package into two: react and react-dom.
The react package holds the react source for components, state, props and all the code that is react.
The react-dom package as the name implies is the glue between React and the DOM. Often, you will only use it for one single thing: mounting your application to the index.html file with ReactDOM.render().
Why separate them?
The reason React and ReactDOM were split into two libraries was due to the arrival of React Native (A react platform for mobile development).
The react package holds the react source for components, state, props and all the code that is react.
The react-dom package as the name implies is the glue between React and the DOM. Often, you will only use it for one single thing: mounting your application to the index.html file with ReactDOM.render().

Resources