In React quickstart, it is stated about Refs and Functional Components that
You may not use the ref attribute on functional components because
they don't have instances:
function MyFunctionalComponent() {
return <input />;
}
class Parent extends React.Component {
render() {
// This will *not* work!
return (
<MyFunctionalComponent
ref={(input) => { this.textInput = input; }} />
);
}
}
I don't fully understand the above statement and the example. So far from reading the tutorials, the only difference between functional and class component is that the latter can have things like constructor and lifecycle management functions.
What does the documentation mean when it says functional components don't have instances? Is it because they don't have this pointer? Is this restriction coming from react or ES6?
React class components extend React.component which is a JS class. They are instances of React.component and inherit features like lifecycle hooks and internal state management from React.component itself. In this sense, I would call them components which have an instance, since React will use the same React.component instance to persist component state during its lifecycle.
React function components are nothing but JS functions: they get a set of properties as input and output a piece of virtual DOM. These functions are re-executed from top to bottom each time React decides the resulting virtual DOM might be out of date. Since plain JS functions don't persist any state by design, state persistence is delegated to a few global React API called hooks.
I faced the same doubt while reading the docs on ref. However, after doing a little more research I found this discussion. (https://github.com/facebook/react/issues/4936#issuecomment-142379068)
Functional components don't have instances because they are mere JS functions. A function can't have an instance. Whereas, classes have instances(objects) of them.
So when the documentation says you can't use ref on functional components because they don't have instances means that -> how can you store the instance of a functional component when it doesn't exist?
Related
I followed the installation guide in https://www.w3schools.com/react/react_getstarted.asp to install React on my system. But after installation, I followed their instructions to open the App.js file only to discover that my own Apps.js has
function App() { ... }
while the one shown on w3schools website has
class App extends Component { ... }
Please is there a problem with my installation?
class is just a special function, and extends means it's using other properties of another function.
just change functionApp(){..} to class App extends Component{..}
as well as adding
import React, { Component } from 'react'
to the top of your page and it should work exactly the same.
You need to dig down more to get the exact knowledge of both the Components as both of them are equally important.
Class based components are state based components means you can change the state (data accordingly)
class App extends React.Component{...}
but in functional component,
function App(props) { ... }
you cannot change the data directly here and whatever is coming in props value you can just show that thus it is called stateless component.You should use functional components if you are writing a presentational component which doesn’t have its own state or needs to access a lifecycle hook. Otherwise you can stick to class components
For more: https://medium.com/#Zwenza/functional-vs-class-components-in-react-231e3fbd7108 https://programmingwithmosh.com/react/react-functional-components/
No, there isn't a problem with your installation. React basically has 2 types of Components: Class and Function. The one created using create-react-app is a Function component whereas w3schools uses Class component for most tutorials. You can find more about them here: W3Schools: React Components
Learn about both of them and use whichever you want according to your use case.
Are Pure, Presentational and Dumb Components all the same thing?
Basically, stateless functional components, which are concern about How Look and not How Work, and are never connected to Redux store?
At a fundamental level, any function that doesn’t alter input data and that doesn’t depend on external state (like a database, DOM, or global variable) and consistently provides the same output for the same input is a pure functions
const add = (a, b) => a + b //pure function
In React, a presentational component or a dumb component is a component that just renders HTML. Their only responsibility is to present something to the DOM.These components are often just Javascript functions. They don’t have internal state to manage. They wouldn’t know how to change the data they are presenting if they were asked. Ignorance is bliss.
In a Redux-powered app, such components do not interact with the Redux store.
However, they accept props from a container component (smart components).
Class-based components that have their own state defined in their constructor() functions
class App extends Component {
constructor(props){
super(props);
this.state = {pictures : []};
}
}
Because container components have the burden of being smart, they are the ones that keep track of state and care about how the app works. They also specify the data and behavior a presentational components should render by passing it down to them as props.If the presentational component has any interactivity — like a button — it calls a prop-function given to it by the container component. But the container component is the one to dispatch an action to the Redux store.
I am wondering, if classes are just syntax sugar for prototypes, and es6 enhances functional coding, can we write reactJS code purely functionally(and without missing out on lifecycle methods)?
[edit]
Think of the most complex react app, can that be written purely functionally - and would it make sense to do that?
EDIT 2019 May:
React Hooks is here: https://reactjs.org/docs/hooks-reference.html
ES6 classes are syntactic sugar for functions and (with some exceptions) it's possible to rewrite them as functions, this is what transpilers like Babel and TypeScript do.
Since component class inherits from React.Component, it needs to prototypically inherit from it. React.Component doesn't have static properties, so a component doesn't need to inherit them.
This component
class App extends React.Component {
state = { name: 'foo' };
componentDidMount() {
this.setState({ name: 'bar'});
}
render() {
return <p>{this.state.name}</p>;
}
}
becomes
function App(props) {
React.Component.call(this, props);
this.state = { name: 'foo' };
}
App.prototype = Object.create(React.Component.prototype);
App.prototype.constructor = App;
App.prototype.componentDidMount = function () {
this.setState({ name: 'bar'});
};
App.prototype.render = function () {
return React.createElement('p', null, this.state.name);
};
This is what now-deprecated React.createClass originally did, create-react-class helper serves this purpose.
if classes are just syntax sugar for prototypes, and es6 enhances functional coding, can we write reactJS code purely functionally(and without missing out on lifecycle methods)?
We can, but functional component isn't the same thing as a component written with desugared JavaScript class. Functional component is specific React term that refers to stateless functional component. Stateless components don't have a state and lifecycle hooks. It's impossible, or at least impractical, to write real React application with stateless components alone.
Think of the most complex react app, can that be written purely functionally - and would it make sense to do that?
Deliberate avoidance of ES6 class syntax doesn't make sense in general because the lack of syntactic sugar results in verbose and unexpressive code without any benefits. A regular React application still needs to use build step and Babel to transpile JSX syntax because desugared JSX is a hierarchy of verbose React.createElement calls. It is practical only if few React components are used in non-React ES5 application that doesn't need build step to be introduced.
However, this may be possible with third-party libraries, e.g. recompose. It's intended to be used with functional components, e.g. lifecycle helper allows to attach lifecycle hooks to them. Of course, it uses component class internally to do that.
you can use stateless component
This article explain
https://hackernoon.com/react-stateless-functional-components-nine-wins-you-might-have-overlooked-997b0d933dbc
example: for stateless component
import React from ‘react’;
const HelloWorld = ({name}) => (
<div>{`Hi ${name}`}</div>
);
export default HelloWorld;
NOTE :
my example lacks lifecycle methods implemented by #estus,so if you don't need those lifecycle methods than you can use below code
Yes you can
import React from ‘react’;
function MyComponent(){
return <div>Hello</div>
}
export default MyComponent;
Live Example
No this is not a way of doing stuff. React gives us two types of components. We use them for a particular purpose.Not everything could be written in stateless components (functions). Stateless components are usually presentation components which only render jsx and have no local state. We can't write methods in stateless components and here comes the Stateful components (class based) where we manage our own state and write methods into it. Further it gives us more control to render our child components. So everything in react follows a pattern and it allows to utilize the power of one way binding.
I'm new to ReactJs and trying to follow best practices. From my research, I've come across a couple of contradicting articles discussing how implementation should be.
Should state rely on the properties being passed down from a parent component? In the comparisons below, they are both following SRP, but not sure which is best. Would like your advice, Thanks!
1. -- Best Practices for Component State in React.js
First, and probably the most important of all, the state of a component should not depend on the props passed in. (see below for example of what we should not do)
class UserWidget extends React.Component {
// ...
// BAD: set this.state.fullName with values received through props
constructor (props) {
this.state = {
fullName: `${props.firstName} ${props.lastName}`
};
}
// ...
}
2. -- 7 architectural attributes of a reliable React component
Let's refactor to have one responsibility: render form fields and attach event handlers. It shouldn't know how to use storage directly.....The component receives the stored input value from a prop initialValue, and saves the input value using a prop function saveValue(newValue). These props are provided by withPersistence() HOC using props proxy technique.
class PersistentForm extends Component {
constructor(props) {
super(props);
this.state = { inputValue: props.initialValue };
}
// ...
}
3. -- In my case, I have something like the following (wondering if this is an acceptable implementation?) - Should state be handled in Tasks, or in another TasksWithPersistence type of component that sits between TasksWithData and Tasks?
export default function TasksWithData(TasksComponent) {
return class withData extends React.Component {
render() {
const tasks = TaskAPI.getTasks();
return (
<TasksComponent
tasks={tasks}
{...this.props}
/>
)
}
}
}
export default class Tasks extends React.Component {
state = {
tasks: [],
addItemInput: null
};
// ...
componentDidMount() {
this.updateComponentState({tasks: this.props.tasks});
}
componentDidUpdate() {
this.prepUIForNextAddition();
}
// ...
}
The gist of your question seems to revolve around the anti-pattern that is to take some props and duplicate it into the state. This, mutating of props, isn't the purpose of the state. Props are immutable, duping them to the state defeats this design.
The purpose of the state is to manage things that are specific to the React Component, i.e. tightly scoped to only that React component. For instance a showHide switch for something to display within the React component. Think of the state as a locally scoped variable if it helps.
Most of the time this anti-pattern of duping the props can be satisfied by a function within the React object. For example, your state.full_name variable becomes a named function, fullName, bound to the React Component. (all code examples are assuming JSX syntax)
Note: in JavaScript camelcase is the naming structure for functions and variables, I'm assuming you're coming from ruby based on the underscore naming convention. IMO it's best to stick to the convention of the language with which you're writing the code. This is why I use camelcased naming.
...
fullName() {
return this.props.firstName + " " + this.props.lastName
}
...
That function can then be called within the render of the component
# in render() portion of your React component, assuming jsx syntax
<p>Hello, {this.fullName()}</p>
Note: Remember that in ES6 you have to bind the methods in your react class in the constructor or use => syntax so that you can call them with this.
...
constructor(props) {
super(props);
this.fullName = this.fullName.bind(this);
}
...
You could also decompose the relevant parts to a new Component called FullName if it will be utilized by multiple components.
<FullName firstName={this.props.firstName} lastName={this.props.lastName} />
Technically, "the react way" is, at least in this author's opinion, to decompose this into another component for reusability. However component reuse needs to be weighed against the complexity added, i.e. don't optimize prematurely. So you may not want to take that too far at first. The times when it's necessary will emerge naturally.
A very broad generalization of React's props is that they are guaranteed, are immutable, and they flow down like a waterfall from the topmost component. If you need to update them, update them at the highest level where it makes sense.
In a soley React based approach, if you have something that a parent needs to be aware of, "lift" that part of the code up to the parent and vice versa bind it down to the child as a props, e.g. an AJAX function that calls an API. I think of it as trying to keep the components as dumb as possible.
The parent becomes the "source of truth" for the item you "lifted". The parent handles the updates, and then passes the results to the children. So in the parent, it may exist as a state variable and then get passed as props to the child object, which then passes it along as props to it's child object, etc. The children would update as the state gets changed in their parent when it propagates down through the chain as props.
If your app is React only, i.e. no stores that manage objects such as in the flux pattern or redux pattern, you may have to store things in the topmost objet's state which technically could be viewed as bad. As your system becomes more complex, this functionality would be better handled by flux or redux's parts.
Hope this helps!
There is a huge difference between example 1 & 2.
In example #1, the reason it's bad to set state from the those props in that way is that if the props change, the widget will not update. Best practices or not, that is just wrong and bad in any framework. In that particular case, there really is no point in even using the state. Props alone will suffice.
In example #2 the prop is only being used to give the state an initial value (The prop is even named initialValue), implying that further changes to the state will be controlled by the component regardless of prop changes. It does not break single responsibility principle to use props for an initial state, especially when it's explicitly use for that purpose.
I really don't see those two examples as being contradictory because they are completely different. Further, there is no rule in single responsibility principle that you can't set state from props, you just need to pay attention to the context in which you are doing it.
One thing I had learned about React is that if the props to a component don’t change, then React doesn’t bother re-rendering the component. Is that true for stateless components too? Or do they behave more like “stupid” functions and get executed every time?
For example, if I had:
import StatelessComponent from '../StatelessComponent';
export default class DocumentsTable extends React.Component {
state = {
something: 'foobar',
};
render() {
return (
<div>
{ this.state.something }
<StatelessComponent theOnlyProp='baz'>
</div>
)
}
};
When this.state.something updates its value, does <StatelessComponent> get re-rendered? Or is it “smart” enough to see that its props didn’t change, like other React components?
UPDATE 25.10.2018
Since React 16.6, you can use React.memo for functional components to prevent re-render, similarly to PureComponent for class components:
const MyComponent = React.memo((props) => {
return (
/* markup */
);
});
Also, memo does internal optimization.
And unlike a userland memo() higher-order component implementation, the one built into React can be more efficient by avoiding an extra component layer.
Blockquote
OLD ANSWER
Yes, they always re-render 1 (unless you use React.memo as explained above) if setState() is called in the component itself or one of its parents, because functional stateless components don't carry a shouldComponentUpdate. In fact, each React component is being re-rendered1 unless they implement shouldComponentUpdate.
Important to note is that calling render() doesn't mean that DOM Nodes are being manipulated in any way. The render method just serves the diff algorithm to decide which DOM Nodes need to really be attached / detached. Note that render() is not expensive, it's the DOM manipulations that are expensive. They are executed only if render() returns different virtual trees.
From React's documentation
Just to be clear, rerender in this context means calling render for all components, it doesn’t mean React will unmount and remount them. It will only apply the differences following the rules stated in the previous sections.
Just don't worry and let render() be called unless your component is huge, then you're better off with stateful Component that implements shouldComponentUpdate().
Look here for an interesting discussion.
1 means that render() function of the component is called, not that the underlying DOM node is being manipulated.
See react does not only rerenders only If props are changed it even rerenders itself if any state change is there. In your case the component will rerender as your state is changing. The way react works is based on an algorithm named Reconciliation, what this algorithm does is that it compares your virtual DOM with real DOM and if it sees any change then it rerender your actual DOM by replacing it with your virtual DOM so any change in state will cause rerendering of the whole component.
Will a Stateless component re-render if its props have not changed?
Yes. Stateless render function will be called even if nothing has changed. However, React will in the reconciliation phase compare the virtual DOM (generated by the render function) against the existing DOM. This is far in the pipeline, hence not ideal if the render function was costly to compute.
A Pure component does have a default shallow comparison of the property and would have stopped the render to be executed. See the Pure component as a normal class React component that has a shouldComponentUpdate that compare with a triple equal the existing properties and the new one.
That being said, you can wrap your Stateless component into a Pure Component by using Recompose.pure (https://github.com/acdlite/recompose/blob/master/docs/API.md#pure) which will automatically perform, like the Pure Component, a shallow comparison without compromising on the short syntax of the Stateless component.
import StatelessComponent from '../StatelessComponent';
const PureChildFromStatelessComponent = Recompose.pure(StatelessComponent);
// ...
<PureChildFromStatelessComponent ... />