React - difference between function and component - reactjs

I'm just starting to learn React, and I noticed that the App.js component which is initially created differs from the one in the tutorials (which are pretty recent).
The one generated looks like this:
import React from 'react';
import logo from './logo.svg';
import './App.css';
function App() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
}
export default App;
The one in the tutorials looks similar, but looks something like this:
import React from 'react';
import logo from './logo.svg';
import './App.css';
class App extends Component {
render() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
)
}
export default App;
Have there been any recent changes to the default App.js?

Yes, this is a quite recent change. It was merged in March 2019.
https://github.com/facebook/create-react-app/pull/6451
In practice there's no difference between the two version of App.js, since the class only implements the render method. Using a class component here is perfectly fine, and there's no plans to get remove class components from react.js.
You will have to ask the create-react-app team why they changed it. They presumably want to use function components wherever possible. With the introduction of hooks in react 16.8, almost everything that used to require class components can now be done using function components.

One is called a functional component and does not have a this.state you can refer to, but rather the UI is controlled by this.props. The other is a full-blown component where you can have this.state. Also, functional components do not have render methods, they just return JSX.
Functional components are usually more performant and should be used when you don't need to use this.setState within a component.
If you wanted to toggle a button on and off within a functional component, you would NOT be able to it using its INTERNAL state - because it does not have one in the first place. You would have to refer to the PARENT component using this.props.isButtonClicked for example like this:
class ParentComponent extends Component {
constructor(props) {
super(props);
this.state = {
isButtonClicked: true,
}
}
render() {
return (
<FunctionalComponent isButtonClicked={this.state.isButtonClicked} />
)
}
}
// | here you can grab the variable
export const FunctionalComponent = ({ isButtonClicked }) => {
if (isButtonClicked) {
return (...clickedButton)
}
return (...unclickedButton)
}
As you can see here the state of the functional-component is defined by the PARENT. The parent's state decides whether it is clicked or not. This is the benefit of having a class-component.
On the other hand, you could make a button with its own internal state to decide if its clicked or no.
EDIT: So with React hooks you can now have state within functional components. My bad.

Related

Is it possible to pass different props from two different files in React?

Suppose I am calling a Component from the index.js and the same component is called off from a different file with a completely different set of props inside a return value. The below images are the two files and the component itself. The Modal component has a dependency on the Home component's toggle state. It will only render when the toggle is true, which is controlled by the button in Home Component. Keep in mind I'm rendering the Modal component in App.js and in Home.js
**This is a small demo of a more realistic situation.
After running this application Modal component is not rendering at all.
So the question is why is this happening internally and how to resolve this situation?
import React, {useState} from 'react'
import logo from './logo.svg';
import './App.css';
import Home from './components/Home';
import Modal from './components/Modal';
function App() {
const [logoR, setLogoR] = useState(logo);
const [currDate, setCurrDate] = useState(new Date());
console.log(currDate);
return (
<div className="App">
<header className="App-header">
<img src={logoR} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
<Home/>
<Modal logoR={logoR} currDate={currDate} />
</header>
</div>
);
}
export default App;
Github repo - React-props
In your handleClick() your return the Modal but nothing is being done with that. It's not being inserted into the DOM anywhere.
Something like this might get you closer.
import React, {usestate} trom 'react' 7.2K (gzipped: 3K)
import Modal from './Modal';
const Home = () => {
const [toggle, set Toggle] = usestate(false);
console.log(toggle);
const handleclick () => {
setToggle(!toggle);
}
return (
<div>
<button
className="App-button"
onclick={handleclick)>
whats up!
</button>
<Modal toggle={toggle} />
</div>
}
export default Home
I would suggest checking out react portals if you have a modal that you will want to trigger from various parts of the app. They have a good example of how to use this with a modal.
https://reactjs.org/docs/portals.html

Just adding useState hook statement causing component to rerender

I have created a basic create-react-app and added the below statement
const [stateA, setStateA] = useState(false);
and I have put a console.log inside my component.
The complete component code is
import React, { useState } from 'react';
import logo from './logo.svg';
import './App.css';
const App = () => {
const [stateA, setStateA] = useState(false);
console.log("rendered");
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
}
export default App;
It is showing "rendered" twice. Can any one tell why this is happening ?
If you notice index.js (as create-react-app now uses React.StrictMode by default ) file you may have a wrapper called React.StrictMode which is responsible for this extra re-render. The wrapper will invoke render, constructor and other lifecycle methods to detect side effects. So this is expected.
You can read more here: https://reactjs.org/docs/strict-mode.html#detecting-unexpected-side-effects
Hope this helps!

function App() vs class App extends Component in the App.js file

I'm following a tutorial on React (https://www.youtube.com/watch?v=sBws8MSXN7A - dated January 3, 2019) and created a React app with npx create-react-app *app_name*. The App.js file this command generated on my computer is different from what this command generated for the person giving the tutorial. Has React changed since then or is it possible I downloaded something wrong?
My App.js:
import React from 'react';
import logo from './logo.svg';
import './App.css';
function App() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
}
export default App;
Tutorial's App.js:
import React, { Component } from 'react'; //different
import logo from './logo.svg';
import './App.css';
class App extends Component { //different
render() ( //different
// The rest of the file is the same
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
}
export default App;
The most obvious difference is the syntax. A functional component is just a plain JavaScript function which accepts props as an argument and returns a React element.
A class component requires you to extend from React.Component and create a render function which returns a React element. This requires more code but will also give you some benefits.
A functional component doesn’t have its own state. If you need a state in your component you will either need to create a class component or you lift the state up to the parent component and pass it down the functional component via props.
Another feature which you cannot use in functional components are lifecycle hooks. The reason is the same as for state, all lifecycle hooks are coming from the React.Component which you extend from in class components. So if you need lifecycle hooks you should probably use a class component.
Conversely, functional components allowed to use hooks where class components are not allowed to.
There are basically two ways of writing components in React: functional and class components. The given examples are no different except for this aspect.
There is one major difference between these methods of defining a component. It's related to the state of the particular React component.
So, Function-Based Components => Are also called Stateless components reason being they don't update to any changes that are being applied to a particular component.
So, If I want to change some value in this <p>Hi, Welcome</p> on a button press to <p>Welcome Back</p>
It wouldn't be possible to use function-based components.
On the other hand, Class-Based Components => Are also called Stateful Components, being that they update to changes that occur to the component.
So, the previous example would work.
Personally, I would say a simple way to remember is Functional Components for static data and Class-Based Components for dynamic and interactive data.
The obvious differences are in the syntax and hints are derived from their names in how they will be written. They both render JSX (which is React’s way of writing HTML and JavaScript), however for the class component you define a class that extends the React.Component library. Additionally, the class component utilizes a render() method. Here’s an example:
App.js: functional component
import React, { Component } from 'react';
import './App.css';
function App() {
return (
<h1>hello</h1>
);
}
export default App;
App.js: class component
import React, { Component } from 'react';
class App extends Component {
render() {
return (
<h1>hello</h1>
);
}
}
export default App;

How to create React.js app without a function in App.js

I just finish typing npx create react app to create a react app but for some reason my App.js is a function not a class
eg)
result:
function App() {
return ()
I want something like:
Class app extends components{
render (return())
}
I could write it down manually but i want the class app as default when i create an app so could anyone tell me what is the cause of this?
That just comes out of the box now for React. You can make your App.js a stateless functional component OR a class component.
class App extends React.Component{
render(){
return(
<div>Hello World</div>
)
}
}
With the introduction of hooks in React 16.8 functional components can be stateful and supposed to replace class components in most cases. This is the reason why App is functional component in a project that is generated with create-react-app, more specifically react-scripts package.
It's possible to initialize the project with older react-scripts as a template:
create-react-app foo --scripts-version react-scripts#^2
And then update it to latest version:
npm -S react-scripts#^3
Since create-react-app provides static boilerplate for a project, and doesn't have scaffolding features, it's possible to copy and paste App from previous react-scripts version:
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
class App extends Component {
render() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
}
}
export default App;
As mentioned by #FaizanMubasher, the class Components were not very reusable, and they were lacking a sense of interchangeability. It makes no sense to copy class component code from previous versions.
It will be ideal to use move away from class components and start using function components.
here is an example for anyone seeking the right approach.
import React from 'react';
import Layout from './components/Layout/Layout';
function App() {
return (
<div className="App">
<Layout />
</div>
);
}
export default App;
function component Layout:
import React from 'react';
import Aux from '../../hoc/Aux';
const layout = (props) => (
<Aux>
<div>TOOLBAR, SIDEDRAWER, BACKDROP</div>
<main>
{props.children}
</main>
</Aux>
);
export default layout;

How To Add My Own Svg Image Just Like Logo Is Shown By Default In Create-React-App

I've got a clean create-react-app install and I wanted to add my own svg image to show, the same way that logo is shown i.e.:
import logo from './logo.svg';
{logo}
However when I import my own svg the same way as logo is imported and try to use it, it prints a url like this on the screen:
/static/media/menu.92677579.svg
instead or rendering the image, could someone help me figure this out please?
When you write {logo} you're just embedding a URL.
If you want to show an image, use the <img> tag like the default template does.
<img src={logo} alt="My logo" />
Hope this helps!
import { ReactComponent as Logo } from './logo.svg';
function App() {
return (
<div>
{/* Logo is an actual React component */}
<Logo />
</div>
);
}
This is a new special syntax when importing SVG in React. The ReactComponent import name is special and tells Create React App that you want a React component that renders an SVG, rather than its filename. You can read more about it here, but keep in mind that this is a React library special syntax:
Reference link: Create React App
I found I could pass in the logo image file (.svg) as a prop from the component "calling ClsSplash". The import in the calling component sent a reference to some sort of optimized svg file at /static/media/logo.5d5d9eef.svg I have no idea where that is or why it is necessary. In any case, I see an animation working referring to that prop.
My ClsSplash is the guts of the default APP.tsx you get when you make a new project with
npx create-react-app hello-world --typescript
I set up another JSX image tag to see how to import the svg file directly within the ClsSpash component. This is works for me running (F5) a "project" within VS2019 launched with IISExpress into Google Chrome 75.0.3770.142 (Official Build) (64-bit)
import * as React from 'react';
import * as logo from './../../logo.svg';
/* imported item has to have the same name as the file name (without extension) */
/* fyi article explains the optimized svg */
/* https://react.christmas/2018/18 to handle a Data URL */
import '../../fldrAppearance/fldrCSS/App.css'; /* for div classname attributes */
class ClsSplash extends React.Component<any, any> {
constructor(props: any)
{
super(props);
}
public componentDidMount()
{
// console.log("logoPath is " + logo);
}
public render()
{
const lclLogo = logo;
console.log("prop logoPath is " + this.props.svg);
return (
<div className="App">
<header className="App-header">
{/*}<img src={logo} className="App-logo" alt="logo" /> {*/}
<img src={`${lclLogo}`} className="App-logo" alt="logo" />
<img src={`${this.props.svg}`} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.tsx</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header >
</div>
)
}
}
export default ClsSplash;
screenshot of two spinning logo svg images

Resources