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

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;

Related

Why this problem happend in my react function?

I'm trying to get information from redux but this error happen and i dont know how could i fix it. That's my first time with react and react Hooks, sorry but i'm lost.
Thank you in advance.
React Hook "useSelector" is called in function "header" which is neither a React function component or a custom React Hook function
My code:
import React from 'react';
import { useSelector } from 'react-redux';
import { Link } from 'react-router-dom';
import Notifications from '../Notifications';
import logo from '~/assets/headerLogo.svg';
import { Container, Profile, Content } from './styles';
export default function header() {
const profile = useSelector(state => state.user.profile);
return (
<Container>
<Content>
<nav>
<img src={logo} alt="GoBarber" />
<Link to="/dashboard">DASHBOARD</Link>
</nav>
<aside>
<Notifications />
<Profile>
<div>
<strong>{profile.name}</strong>
<Link to="/profile">Meu Perfil</Link>
</div>
<img
src={
profile.avatar.url ||
'https://api.adorable.io/avatars/50/abott#adorable.png'
}
alt="profile"
/>
</Profile>
</aside>
</Content>
</Container>
);
}
The rules of hooks lint plugin depends on naming conventions to tell what is a component, what is a hook, and what is any other function. Functions beginning with use (eg, useEffect, useMyCustomStuff) are assumed to be hooks. Functions beginning with a capital letter are assumed to be components. Your code does neither, so it assumes this is just a normal function unrelated to hooks or components.
Rename header to Header to fix this.

React - difference between function and component

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.

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;

Why does the page flash all green (in react Rendering chrome addon) when changing anything in redux store

I've created a simple app to test what part of the document gets rerendered when I add items to an array and then use .map in react. To manage the state I use redux. To check what gets rerendered I use the react chrome addon with the option Paint flashing selected.
So I expect that when I dispatch an action from a component that modifies the store, only the components connected to that part of the store would flash green. Instead, the whole screen flashes green followed by every single component that will also flash green.
Seems like anything under <Provider /> will just update on any change inside redux store.
I've already tried PureComponent, managing shouldComponentUpdate, React.memo for the function component.
My index file looks like:
import React from "react";
import ReactDOM from "react-dom";
import { Provider } from "react-redux";
import { createStore } from "redux";
import reducers from "./store/reducers";
import "./index.css";
import App from "./App";
const store = createStore(reducers);
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById("root")
);
And my App file:
import React, { Component } from "react";
import logo from "./logo.svg";
import "./App.css";
import ListComp from "./components/ListComp";
import ListFunc from "./components/ListFunc";
import ButtonMore from "./components/ButtonMore";
export class App extends Component {
shouldComponentUpdate() {
return false;
}
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>
<ButtonMore />
<ListComp />
<ListFunc />
</div>
);
}
}
export default App;
ButtonMore will add items to the store when clicked. It has the action connected so it can dispatch it.
ListComp is connected to the list of items in the store and will .map them. In this case, the main purpose was to test the key property and see if only the new items would flash green.
ListFunc Will do the same as the one above but as a function component.
I wanted to drive this test since in the project I work on we are going crazy with performance issues now that the app is huge. We are thinking of moving away from redux but I don't think this option is good at all.
I expected some green flashes just on the new items displayed. But instead the whole screen will always flash when I change anything in the store.
EDIT: Let me add the example that shows the list of items from the store. I expected this to flash only the new items but instead it flashes the whole component:
import React from "react";
import { connect } from "react-redux";
const ListFunc = props => {
return (
<ul className="ListComp">
{props.listItems.map((item, i) => {
return <li key={`itemFunc_${i}`}>{item}</li>;
})}
</ul>
);
};
const mapStateToProps = state => {
return { listItems: state.reducer };
};
export default connect(
mapStateToProps,
null
)(ListFunc);
React-Redux v6 changed the internal implementation in several ways. As part of that, the connect() wrapper components do actually re-render when an action is dispatched, even when your components don't.
For a variety of reasons, we're changing that behavior as part of v7, which is now available as a beta.
update
After looking at the code snippet you've posted: yes, I would still expect the example you've shown to cause both the list items and the list to re-render. I can't say 100% for sure because you haven't shown your reducer, but assuming that one of the list items is updated properly, state.reducer should be a new array reference as well. That will cause ListFunc to re-render.

Using Material-UI muiThemeable within the render function of a component?

Im currently using material-ui for my web app and would like to add themes to it so Im using the MuiThemeProvider it comes with to theme it.
The documentation contains instructions on how to use custom components with themes but it unfortunately lacks instruction on how to use it from within a render function.
For example, in the the code they use is:
import React from 'react';
import muiThemeable from 'material-ui/styles/muiThemeable';
const DeepDownTheTree = (props) => (
<span style={{color: props.muiTheme.palette.textColor}}>
Hello World!
</span>
);
export default muiThemeable()(DeepDownTheTree);
Which is fine, but if you need the render function, this wont do. How would I achieve something similar to this? (This wouldnt work, just an example):
import React from 'react';
import muiThemeable from 'material-ui/styles/muiThemeable';
class MyComponent extends React.Component{
render(){
return muiThemeable()(
<span style={{color: props.muiTheme.palette.textColor}}>
Hello World!
</span>
)
}
}
export default muiThemeable()(DeepDownTheTree);
This is critical for my application as I manipulate bits of my DOM in the render function before returning the final DOM.
The equivalent statefull component to your initial stateless component would be
import React from 'react';
import muiThemeable from 'material-ui/styles/muiThemeable';
class MyComponent extends React.Component{
render(){
return (
<span style={{color: this.props.muiTheme.palette.textColor}}>
Hello World!
</span>
)
}
}
export default muiThemeable()(DeepDownTheTree);
Note that you use the higher order function (that's the muiThemable()) on the entire component, not on just what is returned from the render function.

Resources