What is happening inside here from what I understand is that you're building out your own render method, which will render the html of the h1. This render method is called by React.DOM to figure out what to give to the virtual dom. The same goes for methods such as componentDidMount right? If you put in any of those lifecycle methods or render, React will call them accordingly to fit inside their code, but if create other functions, those will just be helper functions for you to render stuff with, right?
I guess I'm just trying to understand which part of the Component class is being used by React.DOM and which parts am I building. It seems weird that some methods are used to "configure" the component while others are used as helpers. What code inside the Component class is the React.DOM using? Is it like stuff to figure out the diffs on when to rerender stuff?
class Greeting extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
Here's something to consider: ages ago in times long past, React and React-DOM were one in the same. React was targeted solely to webapps. So we could use h1, div, span, img, all of that using React only.
Now let me ask you this question. Let's say they wanted to take React, and make it so it could not only render to the DOM of a webpage, but also render the different components of a native mobile application? What would you do in that situation?
Obviously, all of those aforementioned HTML DOM elements, h1s etc etc, would be utterly useless! Android and iOS interiors do not know what any of those are whatsoever.
So the logical solution is to abstract that away. Instead of having those DOM nodes be an inherent part of React, instead make it so that React can render wherever and whatever!
You see, the React engine works pretty much the same in both React Native (mobile development), and standard web-based React with React-DOM. The lifecycle methods, the principles of design, the reconciliation, the entire engine is the same. Because React isn't about HTML or native applications, it's about a paradigm of data flow from application state into UI state.
So then, what is React-DOM doing with your component? Not a whole lot of anything, really. All of the diffing, data flow, etc etc are all handled by React.
What React-DOM does is it knows how to render the data provided by a React element as a DOM node. It knows how to update them, how to delete, them, all of that. You see, having all those abilities as part of the React core would not be ideal now, because React targets other platforms where those abilities are useless. And they would only bloat the package.
The only method inside the class you 'have' to provide is the render. The other component lifecycle methods, as you mentioned, are called if provided when those lifecycle methods come into play. If you have no need to tap into those other lifecycle methods (component just returns some markup based on props provided to it) and your component doesn't need its own state then I would highly recommend just using stateless functional components. The docs provided by React team are good for explaining this -
https://facebook.github.io/react/docs/components-and-props.html
As far as the 'helper methods' you mentioned, yes you can define as many methods as you need in your class. It is very common to split up some of the more complex rendering logic into smaller easier to read functions for code readability.
Related
With the introduction of hooks in React, the main confusion now is when to use function components with hooks and class components because with the help of hooks one can get state and partial lifecycle hooks even in function components. So, I have the following questions
What is the real advantages of hooks?
When to use function components with hooks vs Class components?
For example, function components with hooks can't help in perf as class components does. They can't skip re-renders as they don't have shouldComponentUpdate implemented. Is there anymore reasons?
The idea behind introducing Hooks and other features like React.memo and React.lazy is to help reduce the code that one has to write and also aggregate similar actions together.
The docs mention few really good reason to make use of Hooks instead of classes
It’s hard to reuse stateful logic between components Generally when you use HOC or renderProps you have to restructure your App with multiple hierarchies when you try to see it in DevTools, Hooks avoid such scenarios and help in clearer code
Complex components become hard to understand Often with classes Mutually unrelated code often ends up together or related code tends to be split apart, it becomes more and more difficult to maintain. An example of such a case is event listeners, where you add listeners in componentDidMount and remove them in componentWillUnmount . Hooks let you combine these two
Classes confuse both people and machines With classes you need to understand binding and the context in which functions are called, which often becomes confusion.
function components with hooks can't help in perf as class
components does. They can't skip re-renders as they don't have
shouldComponentUpdate implemented.
Function component can be memoized in a similar way as React.PureComponent with Classes by making use of React.memo and you can pass in a comparator function as the second argument to React.memo that lets you implement a custom comparator
The idea is to be able write the code that you can write using React class component using function component with the help of Hooks and other utilities. Hooks can cover all use cases for classes while providing more flexibility in extracting, testing, and reusing code.
Since hooks is not yet fully shipped, its advised to not use hooks for critical components and start with relatively small component, and yes you can completely replace classes with function components
However one reason that you should still go for Class components over the function components with hooks until Suspense is out for data fetching. Data fetching with useEffect hooks isn't as intuitive as it is with lifecycle methods.
Also #DanAbramov in one of his tweets mentioned that hooks are designed to work with Suspense and until suspense is out it's better to use Class
Hooks greatly reduce the amount of code you need to write and increase its readability.
It is worth noting though that there are hidden processes going on behind (Just like component did mount etc.) that mean if you don't understand what is going on it can be difficult to troubleshoot. It is best to experiment with them and read through the docs fully before implementing on a live project.
Also there is still limited support/documentation for testing hooks compared to classes.
https://dev.to/theactualgivens/testing-react-hook-state-changes-2oga
Update 28/08/2020
Use the react hooks testing library with custom hooks for testing
https://github.com/testing-library/react-hooks-testing-library
Officially it sounds like hooks will completely replace classes?? maybe one day, but think about it; hooks have been around for 3 years (as of Mar 2021), and there are pros and cons in adopting them (More pros than cons... don't get me wrong)
I have plenty more experience myself with state management/classes and after doing a lot of research and testing, I found out that we need to know both classes and hooks very well. Hooks require a fraction of the code for simple components and seem excellent for optimizing HOCs. Meanwhile classes seem better with routing, container components and asynchronous programming for example.
I'm sure there are plenty more cases where each technology is better, but my point is that programmers need know both hooks and classes very well specially when working on projects with 100,000+ lines of code and millions of users. Read more here: https://stackoverflow.com/a/60134353/11239755
With the introduction of hooks in React, the main confusion now is when to use function components with hooks and class components because with the help of hooks one can get state and partial lifecycle hooks even in function components. So, I have the following questions
What is the real advantages of hooks?
When to use function components with hooks vs Class components?
For example, function components with hooks can't help in perf as class components does. They can't skip re-renders as they don't have shouldComponentUpdate implemented. Is there anymore reasons?
The idea behind introducing Hooks and other features like React.memo and React.lazy is to help reduce the code that one has to write and also aggregate similar actions together.
The docs mention few really good reason to make use of Hooks instead of classes
It’s hard to reuse stateful logic between components Generally when you use HOC or renderProps you have to restructure your App with multiple hierarchies when you try to see it in DevTools, Hooks avoid such scenarios and help in clearer code
Complex components become hard to understand Often with classes Mutually unrelated code often ends up together or related code tends to be split apart, it becomes more and more difficult to maintain. An example of such a case is event listeners, where you add listeners in componentDidMount and remove them in componentWillUnmount . Hooks let you combine these two
Classes confuse both people and machines With classes you need to understand binding and the context in which functions are called, which often becomes confusion.
function components with hooks can't help in perf as class
components does. They can't skip re-renders as they don't have
shouldComponentUpdate implemented.
Function component can be memoized in a similar way as React.PureComponent with Classes by making use of React.memo and you can pass in a comparator function as the second argument to React.memo that lets you implement a custom comparator
The idea is to be able write the code that you can write using React class component using function component with the help of Hooks and other utilities. Hooks can cover all use cases for classes while providing more flexibility in extracting, testing, and reusing code.
Since hooks is not yet fully shipped, its advised to not use hooks for critical components and start with relatively small component, and yes you can completely replace classes with function components
However one reason that you should still go for Class components over the function components with hooks until Suspense is out for data fetching. Data fetching with useEffect hooks isn't as intuitive as it is with lifecycle methods.
Also #DanAbramov in one of his tweets mentioned that hooks are designed to work with Suspense and until suspense is out it's better to use Class
Hooks greatly reduce the amount of code you need to write and increase its readability.
It is worth noting though that there are hidden processes going on behind (Just like component did mount etc.) that mean if you don't understand what is going on it can be difficult to troubleshoot. It is best to experiment with them and read through the docs fully before implementing on a live project.
Also there is still limited support/documentation for testing hooks compared to classes.
https://dev.to/theactualgivens/testing-react-hook-state-changes-2oga
Update 28/08/2020
Use the react hooks testing library with custom hooks for testing
https://github.com/testing-library/react-hooks-testing-library
Officially it sounds like hooks will completely replace classes?? maybe one day, but think about it; hooks have been around for 3 years (as of Mar 2021), and there are pros and cons in adopting them (More pros than cons... don't get me wrong)
I have plenty more experience myself with state management/classes and after doing a lot of research and testing, I found out that we need to know both classes and hooks very well. Hooks require a fraction of the code for simple components and seem excellent for optimizing HOCs. Meanwhile classes seem better with routing, container components and asynchronous programming for example.
I'm sure there are plenty more cases where each technology is better, but my point is that programmers need know both hooks and classes very well specially when working on projects with 100,000+ lines of code and millions of users. Read more here: https://stackoverflow.com/a/60134353/11239755
I find a bit of a discrepancy in React docs. In the section on Components and Props, they explain, through the example of a functional Welcome component, that
React calls the Welcome component with {name: 'Sara'} as the props.
Fair enough, given that the component is a pure function. Then in State and Lifecycle, they mention, through the example of a class Clock component, that
React calls the constructor of the Clock component. [...] React then calls the Clock component’s render() method.
From reading the docs, as well as this Medium post, with functional components,
the component is invoked directly as a function with props object
it returns a React element, i.e. an object that models the DOM element(s) to be rendered
React DOM then creates and inserts a DOM node to the "real" DOM
The flow is different with class-based components:
the component class is instantiated and the object instance is stored in memory
the render method is invoked and the React element (object) is returned
the React element, backed by its class instance, is used by React DOM to generate and mount an actual DOM node
The big difference, according to the article, is that "function components don’t have instances", meaning that they are invoked directly. React DOM "just uses the invocation of the function to determine what DOM element to render for the function".
However, this is incogruent with other sources. For instance, here and here Dan Abramov mentions that functional components are classes internally. In other words, React will just wrap a functional component into a class and instantiate it, as if it were a class component. Another article goes as far as saying that the former are even slower than the latter.
Question
Are functional components converted into class components by React?
Is there (yet) any performance benefits to using functional, rather
than class components? (e.g. here it says no benefits yet, I assume before React Fiber?)
Should I really sacrifice my workflow, if I
could have state across the app, where it would logically fit in, e.g. a form/controlled component somewhere deep down the tree?
Are functional components converted into class components by React?
There is no “optimized” support for them (functional component) yet because stateless component is wrapped in a class internally. It's same code path.
From a twitter thread by Dan Abramov.
Is there any performance benefits to using functional, rather than class components?
Apparently right now there is no performance benefits because React does a lot of things on Functional Components which decreases performance. Read this to gain more understanding.
Should I really sacrifice my workflow
I guess not
Just a quick question to anybody fond of react
I've made a jsbin example and I'm trying to observe if react is doing any memory optimizations for stateless components
If you heapdump that window you should be able to see BsDiv instance. Does it mean that all components I use will be held in run-time?
(I am not holding any reference to that object myself)
I am worried about this because react components are composed from other ones and so on - which means there could easily be like 5 instances for any Panel, Alert and whatever I will be willing to use.
Is it expected to behave this way?
First: note that React has a special syntax for stateless functional components. Your sample code is not using that syntax and so React does not know your components are stateless.
This is not a stateless functional component:
class BsDiv extends React.Component{
render(){
return (<div className={this.props.cls}>{this.props.children}</div>)
}
}
These are stateless functional components:
// component is just a function
const BsDiv = props => <div className={props.cls}>{props.children}</div>
// Using object destructuring syntax
const BsDiv = ({cls, children}) => <div className={cls}>{children}</div>;
Second: React does not yet apply any significant optimizations for Stateless functional components.
From their blog (emphasis mine):
This pattern is designed to encourage the creation of these simple components that should comprise large portions of your apps. In the future, we’ll also be able to make performance optimizations specific to these components by avoiding unnecessary checks and memory allocations.
So, by writing stateless functional components, you are opting in to future optimizations React makes for this "simpler" components.
Here is some more information on possible future optimizations:
https://github.com/facebook/react/issues/5677#issuecomment-165125151
How will React 0.14's Stateless Components offer performance improvements without shouldComponentUpdate?
Good news and bad news.
First the bad news. What you're observing is correct and expected. React components are just JavaScript objects, so each instance will allocate separately. Furthermore the leaves of React components typically result in many virtual DOM components for every rendered component, which are all in memory as well.
However the good news is very good. In React we typically only render what's visible on the page. So in practice memory allocation is rarely an issue. For example in JQuery style frameworks it's common to render all tabs of a web app whether they are visible or not. The tab switching then just sets a "visible" class on the selected tab. In contrast in React the content of unselected tabs is typically not rendered unless the tab is selected.
So I am looking to write integration level tests (where you are talking to a real database and really nothing is mocked) for a ReactJS application and figured Selenium is the default choice for this type of testing. With Angular 1.x, you can tell if angular's digest cycle is still process the DOM which removes the need to add in sleeps which are inefficient and flakey.
Is there something similar in ReactJS that I can use instead of a bunch of flakey sleep commands?
Always rendering from a root component
There's a callback that you can pass to the render function:
ReactComponent render(
ReactElement element,
DOMElement container,
[function callback]
)
You can also listen to the componentDidUpdate method of that top component.
Unfortunately this will only work if you always render from the top component, which somehow means you manage all the state outside of React, without using any local state, and use it in a purely functional way as an efficient templating engine. Some frameworks help you do so.
Even Flux does not really enforce this (at least the original implementation) because Flux stores are not necessarily injected as props from the very top. (They are in atom-react)
Not always rendering from a root component
I don't know there is any elegant solution to this problem but here's what I would do:
Implement all lifecycle methods on all your components, for example with a Mixin, and call a global function notifyReactIsWorking from these callbacks
Debounce the notifyReactIsWorking with _.debounce(changeMeter, 1000, false)
This way, when notifyReactIsWorking gets called, this somehow means that React has stabilized because not a single lifecycle method has been called for more than 1 second.
This is a hack but probably should work in most cases.
Also interested in more efficient solutions :)