Why should you `extend` Component in React (Native)? - reactjs

I'm quite new in this react ecosystem, but it's pretty clear so far on what a component is and how to create one using:
export default class NotificationsScreen extends Component {
render() {
return(<View></View>);
}
}
however I've seen some examples that just use
const MySmallComponent = (props) => <View></View>
And the app seems to work just as fine..
What is the advantage of extending Component?

Since React is strongly connected to functional programming, it's always a good habit to write pure functions in React. If your component doesn't need to manage state or involve lifecycle methods then use stateless component:
It just feels more natural that way
Easier to write, easier to read
No extends, state and lifecycle methods mean faster code
You can even find more reasons at this article. So, all I want to say is, always use stateless component if you don't need to manage its state.

Dan Abramov coined the terms Smart and Dumb components. Later, he called them Container and Presentational components. So
export default class NotificationsScreen extends Component {
render() {
return(<View></View>);
}
}
is a Container and
const MySmallComponent = (props) => <View></View>
is Presentational components.
Presentational Components are only used for presentaion purposes i.e they rarely have their own state and they are just used to show data on UI by receiving props from parent component or include many child component inside of them. Presentational Component don't make use of react lifecycle methods.
Where as Smart components or Containers usually have state of their own and make use of lifecycle methods of react and also these components usually have their own state.

Related

Const = () => vs Class Functions function name() {} in React Native

I'm new to react native, I'm bit confused about components.
As I created first react native app I saw App.js the components in App.js created as per following code:
export default function App() {
...
}
and as I saw tutorials many people almost all people making components as per following code:
const FirstComponents = () => {
...
}
I'm also confuse about function components and class based components which created as per following code:
export default class FirstComponents extends Components(){
...
}
What is the difference between function and class base components?
Please provide me answer with examples. Your time will be appreciated.
In javascript there are multiple ways to create a function. For example:
function myFunction () {
//some action
}
const myFunction = () => {
//some action
}
These two are functions and makes the same thing.
Now second part of your question is "What is the difference between functional and class based components?"
Class based components used for controlling your state and for lifecycle methods(ComponentDidMount and etc...) in the past. And if you are not using state in your component or lifecyle methods, you would use functional based component. Basically if you have a small component with only some UI things, it was best to use functional components. However with React version 16.8 React team intruduced hooks.
Hooks provides the same concepts with your state and component lifecyle methods and more. With hooks you can control your component even if they are funcitonal components.
The first two snippets are similar in terms of declaration. Both are functional components. These are different from class based components. There are several differences:
Hooks can be used in only functional component, class based can't.
constructor is used to initialize this in the class component but in functional you don't require this.
Lifecycle hooks are not available in the functional component, they are part of class component.
You can use useEffect hook for a lifecycle hook like componentDidMount.
For a short example:
function App(){
const [count, setCount] = useState('');
}
In the above example "count" is a local state property of component and setCount is a method which updates the state.
class App extends React.Component{
constructor(props){
super(props);
this.state = { count: 0 };
this.increaseCount = this.increaseCount.bind(this);
}
increaseCount(){
this.setState({count: this.count+1});
}
// lifecycle methods like componentDidMount, componentDidUpdate etc.
render(){
return(
<button onClick={this.increaseCounter}>INCR</button>
);
}
}
In this class component you can see state is defined in the constructor and it is been updated with the setState method.
real time example will be too much to add, rather i suggest you to take simple examples to have a grasp of the concepts.

What is the difference between Class and Const when creating UI in react-Native?

const App = () => (
<View>
<Text>Test</Text>
</View>
)
class App extends Component {
render() {
return (
<View>
<Text>Test</Text>
</View>
);
}
}
When I test, two things are the same.
Please tell me the difference between these two.
A Class Component is a stateful component and const App is a stateless (or functional) component.
A stateful component is used to:
initialize the state
modify the state
render something
Additionally it has lifecycle methods.
Whereas a stateless component is often just used to return a piece of UI.
In short: a class component is more powerful than a functional component
EDIT:
Since React Native 0.59 also functional components can have a state. See Hooks-Intro for more information.
Using class you can access life cycle hook and you can store a state in the class. Using class you can build stateful component or smart component. Meaning that you handle logic in your class component like doing http request
Using functional component. In this case is const you can build dump component or stateless component (component only use to display data). This is a great way to keep your react code maintainable and readable. Breaking it up into smaller components and passing props to child components.
You can read it more here because is very long expain so I just give you brief overview
Regards
Class will be for containers components. "smart" functional component that conatins State. and data and previewing "dumb" view components.
The "dumb" functional component is used to preview something or better say. render something that is usualy sent from a container.
Now days using hooks you can get the whole life cycle of the class component in a functional component. The only difference is that the functional is state less!

What is the difference between React component and React component instance?

I am reading this and it says:
When a component is purely a result of props alone, no state, the
component can be written as a pure function avoiding the need to
create a React component instance.
What's the difference between a component and a component instance ?
Are they the same ?
EDIT:
What is the difference between Component and Component Instance ?
How do they relate to each-other ?
Conceptually ?
How are they represented in computer memory? How does the representation differ ?
What is a component and what is an instance of that component ? (In memory.) What kind of JS Object ?
Instance in what sense ? Object oriented sense ?
Is it true that every component can have (one or more) instance(s) ?
How many instances can a component have ?
Does it even make sense to say that an instance can be created for a/every react component ?
How are react component instances created and how are components created ?
Reason for asking:
I am trying to create a concept map of react to clarify the terminology and how they relate to each other.
Here is a draft:
The basic difference is, when it a Component, React will run/add all its Lifecycle methods. This will be useful when you have state in your component. When you use this component, React will create a React Component Instance which will have all the lifecycle methods and other hooks added to it.
class App extends React.Component{
...
}
In some cases, you won't use state. In those cases, adding all those lifecycle methods are unnecessary. So, React gives you an way to create an component which will have render alone. It is called PureComponent. When you use this, there is no need to create a new Component Instance because there is no lifecycle methods here. It'll just be a function which can take props and return React Elements.
class App extends React.PureComponent{
...
}
Hope this helps!
[Update]
What is a Component and a Component Instance?
Technically, a Component in React is a class or a function.
Example:
class App extends React.Component{
...
}
//stateless component
const App = (props) => {
...
}
When you use that component, it'll be instantiated, more like new App(). But, React does it by itself in a different way.
For Example:
render(){
return <App/> //Instance of the component App
}
Instances are required because, each instance can perform individually. Instances are a copy of original class.
Simple answer is, components will be a Class and component Instance will be the copy/instance of the class and will be used in render
Hope this explains!
A "React component instance" is just an instance that was created from a previously defined class component. See the example below (es6/JSX) which contains both props and state:
class MyComponentClass extends React.Component {
constructor(props) {
super(props);
// Set initial state
this.state = {
example: 'example'
};
}
render() {
return <div>
<div>{this.state.example}</div>
<div>{this.props.example}</div>
</div>;
}
}
If you have no need for state in your component you can use a pure, stateless, functional React component like so:
function MyStatelessFunctionalComponent(props) {
return <div>{this.props.example}</div>;
}
Here is some more information about stateless React components when they were introduced in React v0.14. Since then you have the ability to use hooks starting in React v16.8, which allow you to define a functional component that has state or makes use of the component lifecyle.
As mentioned in some other comments, there are many performance benefits when using stateless components. These types of components are perfect for when you want something purely presentational as an example.
Since there’s no state or lifecycle methods to worry about, the React team plans to avoid unnecessary checks and memory allocations in future releases.

Should React lifecycle methods be implemented in container components or presentation components?

I'm attempting to implement container components in React and Redux, and I'm unsure of what should take responsibility for lifecycle methods; containers or presentational components. One could argue that the lifecycle methods are presentational as they control DOM updates, but in that respect, aren't they also behavioural?
Furthermore, all of the implementations of container components that I've seen thus far utilise the react-redux bindings, as do my own. Even if I keep the concerns clearly separated, is it appropriate to inherit from React.Component in the case of a behaviour component?
For example, the app on which I'm working has a Tab presentational component, with a shouldComponentUpdate method:
class Tabs extends Component {
shouldComponentUpdate(nextProps) {
const { activeTab } = this.props;
return activeTab !== nextProps.activeTab;
}
[...]
}
On the one hand, this seems like a presentational concern as it controls when component should re-render. On the other hand, however, this is a means of handling when the user clicks a new tab, updating the application's state via an action, thus I'd class this as behavioural.
Data should be controlled as close to the root of the tree as possible. Doing this provides some simple optimizations, being that you're only passing what you need.
This will bubble down to where you are controlling some lifecycle components. As mgmcdermott mentioned, a lot of lifecycle components really depend on what you're doing, but the best case scenario is to have the simplest, dumbest components.
In most of my projects, in my react directory, I have components/ and views/. It is always my preference that a view should do as much of the grunt work as possible. That being said, there a a number of components that I've built that use lifecycle methods like componentDidMount, componentWillMount, componentWillUnmount, but I typically try and isolate updates in my views, since one of their jobs, in my opinion, is controlling data flow. That means componentShouldUpdate would live there. Personally, I think componentShouldUpdate is purely end-of-the-line optimization, though, and I only use it in cases where I'm having large performance issues during a re-render.
I'm not super sure I understand your "inherit from React.Component" question. If you're asking whether or not to use pure functions, es6 class, or React.createClass, I don't know that there is a standard rule, but it is good to be consistent.
To address whether or not you are dealing with a behaviour or presentation, behaviour is the click, but re-drawing is presentation. Your behaviour might be well off to exist in your Tab component, where the re-draw in your Tabs view. Tabs view passes your method from redux to set the currently active tab into your individual Tab components, and can then send the behaviour of tab switching through redux so you can do your presentation componentShouldUpdate. Does that make sense?
So your mapToDispatch method in your container will have a function to set your active tab, let's call it activateTab(idx), which takes a 0-based index of the tab. Your container passes that to the containing component that you control, which is views/Tabs, and it passes that method along to components/Tab. components/Tab will have an onClick method which is listening on one of your DOM elements, which then calls this.props.activateTab(myIndex) (you could also pass a bound version of activateTab into components/Tab so it does not have to be aware of it's own index), which triggers redux, then passes back your data into views/Tabs which can handle a componentShouldUpdate based on the data from redux.
Expanded Edit: Since this was marked as accepted, I'll blow out my code example into something usable to the average person.
As a quick aside, I'm not going to write much redux, as this can be very app dependent, but I'm assuming that you have a state with activeTabIdx hanging off the parent.
containers/TabExample.jsx
import { connect } from 'react-redux'
import Tabs from 'views/Tabs.js'
const mapStateToProps = function (state) {
return {
activeTabIdx: state.activeTabIdx
// And whatever else you have...
}
}
const mapDispatchToProps = function (dispatch) {
return {
activateTab: function (idx) {
dispatch({
action: 'ACTIVATE_TAB_IDX',
idx: idx
}) // You probably want this in a separate actions/tabs.js file...
}
}
}
export default connect(mapStateToProps, mapDispatchToProps)(Tabs)
views/Tabs.js
import React, { createClass } from 'react'
import Tab from 'components/Tab.js'
const { number, func } = React.PropTypes
// Alternatively, you can use es6 classes...
export default createClass({
propTypes: {
activeTabIdx: number.isRequired,
activateTab: func.isRequired
},
render () {
const { activeTabIdx } = this.props
const tabs = ['Tab 1', 'Tab 2', 'Tab 3']
return (
<div className='view__tabs'>
<ol className='tabs'>
{this.renderTabLinks(tabs, activeTabIdx)}
</ol>
</div>
)
},
renderTabLinks (tabs, activeTabIdx) {
return tabs.map((tab, idx) => {
return (
<Tab
onClick={this.props.activateTabIdx.bind(this, idx)}
isActive={idx === activeTabIdx}
>
{tab}
</Tab>
)
})
}
})
components/Tab.js
import React, { createClass } from 'react'
const { func, bool } = React.PropTypes
// Alternatively, you can use es6 classes...
export default createClass({
propTypes: {
children: node.isRequired,
onClick: func.isRequired,
isActive: bool.isRequired
},
handleClick (e) {
const { isActive, onClick } = this.props
e.preventDefault()
if (!isActive) {
onClick()
}
},
render () {
const { children, isActive } = this.props
const tabClass = isActive
? 'tabs__items tabs__items--active'
: 'tabs__items'
return (
<li className={tabClass}>
<a className='tabs__item-link' onClick={this.handleClick}>
{children}
</a>
</li>
)
}
That will mostly do the right thing. Keep in mind that this doesn't handle/care about tab content, and as a result, you may want to structure your view differently.
I think that this is a matter of opinion. I personally like to keep my presentational components as dumb as possible. This allows me to also write most of my presentational components as stateless functions, which are being optimized more and more in React updates. This means that if I can help it, I will prevent any presentational component from having an internal state.
In the case of your example, I don't believe that it is a presentational concern because componentShouldUpdate is a pure function of the props, which should be passed whenever this component is used. Even though this component updates the application's state, I believe that because it has no internal state, it is not necessarily behavioral.
Again, I don't think there is really a right or wrong way of doing things here. It reminds me of the discussion about whether or not Redux should handle all application state. I think if you keep the idea of making presentational components as dumb (reusable) as possible, you can figure out the correct place to put lifecycle methods in any case.
Your question is not very correct.
Simple act of using a lifecycle method doesn't define the component as a presentational or a container component.
Lifecycle methods are exactly that — the hooks for your convenience where you can do pretty much anything you want.
A container component typically does some setup that connects itself to your application's data flow in those lifecycle methods. That's what makes it a container component, not the bare fact that it uses some lifecycle methods.
Presentational components are typically dumb and stateless, therefore they typically don't need those lifecycle methods hooked into. This doesn't mean that it's always the case. A presentational component may be stateful (although this is often undesired) and a stateless component may make use of the lifecycle methods, but in a totally different fashion than a container component would. It might add some event listeners to the document or adjust the cursor position of an input in a totally stateless way.
And perhaps you're mixing up container components and stateful components. Those are different things, and while container components are stateful, stateful components don't necessarily acts as container components.

Functional react component vs React.Component when using propTypes

React 0.14 introduced pure functions as components like this:
export const Label = ({title} => (
<span>{label}</span>
)
However, I also want to describe to the component user which properties and types the component supports and which are the defaults.
So I have to add
Label.propTypes = {
title: React.PropTypes.string.isRequired
}
Label.defaultProps = {
title: "unknown"
}
I could also just use a React.Component like this:
class Label extends React.Component {
static propTypes = {}
static defaultProps = {
title: "unknown"
}
render() {
<span>{this.props.label}</span>
}
}
Everything would be instantly visible and the component understandable.
Why should we use functional components then?
The reasons I see to use functional components even in your case:
No ES6 or React magic on component scale, so the output JS is much shorter.
Cleaner separation. You have a function that return a presentational component. The "meta" data like default props are separated juste like ES6 components.
As stated in the doc, React would like to provide special optimizations to functional components so it might be better performance-wise in the future to use them than regular components for presentation purposes :
In an ideal world, most of your components would be stateless functions because in the future we’ll also be able to make performance optimizations specific to these components by avoiding unnecessary checks and memory allocations. This is the recommended pattern, when possible.
It is not necessary to use the pure function components, the reason they were created was to facilitate the creation of stateless functional components without the need to extend the Component class. This article stateless-components-in-react explains the point in details.

Resources