Very new to react,
I have a class like:
export const Checkbox = ({ label, className }) => {
....
....
return(
.............
.............
);
}
In such a class how can I specify add a componentDidMount and componentWillReceiveProps?
Edit:
I have a layman's doubt, which is the correct way to create a wrapper react component for checkbox? functional component or by extending from Component? If I create a Checkbox wrapper component for others to use, will it be possible for them to connect to a store (say redux) from their pages?
Thanks,
Santhosh
You can't.
These are functional components and do not support React's lifecycle methods.
If you want to use React's lifecycle methods, you need a class that inherits from React.Component
See example below.
class Example extends React.Component {
componentDidMount(){
//code here
}
}
Here is a good answer explaining the differences and when to use functional over class components.
UPDATE from React 16.8
Lifecycle methods can now be used with the introduction of hooks.
If you wished to implement componentDidMount you would use the useEffect hook and pass an empty array as the second argument. An example would look like as follows.
const Example = () => {
React.useEffect(() => {
// do stuff here
}, []);
}
You can't.
If you want to use React's lifecycle methods, you need a class that inherits from React.Component.
export class Checkbox extends React.Component {
componentDidMount() {
....
}
render() {
const { label, className } = this.props;
....
}
}
You cannot. You should create a class that extends PureComponent or Component if you need lifecycle methods.
Related
I've seen code like this
function abc(){
return 'abc'
}
class MyComponent extends React.Component {
static abc = abc;
render() { return <h1>{this.abc}</h1>; }
}
where function abc is defined outside of a react class. I have no clue why the author did it that way, why can't just do it within the class?
These are ES6 static methods and are not exclusive to React. They are members of the component class and not of instances of the component. They are not used extensively in React, but they can be useful. It is even mentioned in the React docs:
Sometimes it’s useful to define a static method on a React component.
For example, Relay containers expose a static method getFragment to
facilitate the composition of GraphQL fragments.
They can be used as common members of the Component, shared by all instances of it. To give you an idea, other static members of a React class are displayName and defaultProps.
Also see Static methods in React. As you can see, there aren't many cases where you would use a static method.
For one thing declaring functions outside the class are easier to EXPORT. Which serves a great deal when testing your react application i.e. through jest.
import React, { Component } from 'react';
class Contacts extends Component {
render() {
return (
Contact()
);
}
}
const Contact = () => {
return (
<div>
<p>Contactssssss</p>
</div>
);
};
export default Contacts;
Note: I encounter this specific problem using React Native, but I guess this goes for React in general as well.
I have a react component built using React.Component.
I don't need to set state, but I do have props. My proposed syntax was as follows:
class Header extends Component {
constructor(props) {
super(props);
}
render() {
return <div>{this.props.title}</div>;
}
}
I understand I can use a function to construct this component, like this:
const Header = (props) => {
return <div>{props.title}</div>;
}
But I prefer the former, because my component will grow, might have state etc, and I just want to keep all my components built in a similar fashion.
Now, my linter complains about having a useless constructor, but how else do I access the props while keeping a class constructor instead of a function constructor?
If you want to use this.props in the constructor, you need to pass props to super. Otherwise, it doesn't matter because React sets .props on the instance from the outside immediately after calling the constructor.
So just simply remove constructor() if useless
you can access props without constructor in a class using "this", like this:
class XXXXXX extends React.Component {
render() {
return (
<div>{this.props.value}</div>
)
}
}
I used to do React.createClass but since I heard it's faster with extends component and since I start to play with babel now, I would like to convert stateless legacy component with the newer style.
I have this
const Main = React.createClass({
render(){
return(<h1>my title</h1>)
}
})
so what's the 'newer' syntax for above code?
is it like this?
const Main = () => {
render(){
return(<h1>my title</h1>)
}
}
Then when to use React.component?
class Main extends React.Components() {
render(){ return(<h1>something</h1>}
}
There is not performance difference between using
const Main = () => {
return(<h1>my title</h1>)
}
or
class Main extends React.Component {
render(){ return(<h1>something</h1>}
}
given they receive the same props, however the react creators suggest that performance improvements will be made in future. So in short,
Use the first approach, which is a functional component approach when your component only takes in props and renders the result. However use the ES6 class based approach, when your React component has more functionality and handles states.
In your case you are just rendering the component so a functional component approach will be best suited for you
Both of your example is correct. Just that the extends Component should be without s and need to import React, { Component } from 'react'; at the top.
const Main = () => {
return(<h1>my title</h1>)
}
You generally want to use the above example when it is does not need any lifecycle methods. This are refer to as Pure component that will always behave the same when given the same props. It also does not keep state.
class Main extends React.Component() {
componentWillMount() {
console.log("I can be not pure");
}
render(){ return(<h1>something</h1>}
}
The above are Component that could manage state and use lifecycle methods.
Usually to decide what to use, I always start with a pure component. When continue developing, I discover that I have to use state or lifecycle methods, I would then turn it to a component.
I've been using this.props and props interchangeably, and for the most part, there doesn't seem to be a major difference between them (as far as I can tell).
However, I've been running into issues lately that make me think that when and why one is used over the other matters.
This is where I'm currently using them interchangeably:
constructor(props, context) {
super(props, context);
this.data = props.card.data;
this.dataLength = this.props.card.data.length;
}
What's the difference and when do you use one over the other, and where?
Thanks!
It all depends on the type of component you are using.
const StatelessComponent = (props) => {
return <div>{props.something}</div>;
}
class SomeComponent extends Component {
constructor(props){
super(props)
}
render() {
return <div>{this.props.something}</div>;
}
}
Here you will notice that in the stateless component it is just a regular function without any this context. The props are passed to the function so we already have access to it.
When you have a class you have a this context that the props live on.
In the constructor of a class the props are passed to the class constructor. So in the context of that constructor function props is passed as an argument and is a local variable
I would recommend you stick to a pattern, when you have props passed as an argument to a function you use props when you are in other methods of a react class you use this.props. That is how it was intended to be used. Also there is something to be said for consistency, so whether you choose one or the other stick with that pattern. It can be confusing if you don't follow a pattern / keep things consistent.
Only in the constructor of React ES2015 components (non-function components) will you be able to refer to props as it is passed into the constructor. If you do this.props === props in the constructor, it will evaluate to true.
However in React, you can only use this.props after you call super(props). This is part of the ES2015 Class spec.
For simplicity, I usually just use solely props within the constructor, and this.props within the component lifecycle methods and in render.
In simple terms:
1.props.data is used in functional components
2.this.props.data is used in Class components
copy the code and run it in "stackblitz" ->https://stackblitz.com/edit/react-3wr8jb
the following code shows usage of both class and functional components with props.data and this.props.data
import React, { Component } from 'react';
import { render } from 'react-dom';
//=================PROPS=======================
//Both Class and Functional components have "properties" ie props
//properties are immutable->fixed->cant be changed
//=================================================
//props.data in functional components
function A1(props)
{
return <h2>functional component->props.data:{props.data}</h2>
}
//===============================================
//this.props.data in class components
class A2 extends React.Component{
render()
{
return<h2>class component->this.props.data:{this.props.data}</h2>
}
}
//===================================================
var element1=
<div>
<hr/>
//data from class and functional component
<A1 data="Sample data" />
<A2 data="Sample data"></A2>
<hr />
</div>
render(element1, document.getElementById('root'));
I am a beginner to react and finding myself confused between mixin and decorators. Can somebody elaborate? Thanks.
They both extend and/or override methods of the React Component. They are used to share common functionality between components, in places where extending a class would not work and is not intended.
An example would be the PureRenderMixin, which overrides the shouldComponentUpdate method and compares the props of a component to decide, if a rerender should be executed.
However, mixins are deprecated and do not work with the ES6 syntax of React anymore. Your options are either to use inheritance or decorators to achieve the same result.
Example
Here is an example of the (kind of) PureRenderMixin, using a decorator. Also I used Immutable.js.
// pure.js
import React from 'react';
import assign from 'object-assign';
import {is} from 'immutable';
/**
* Pure Render Decorator
* #param props
* #returns {function()}
*/
export default (...props) => (Component) => class PureComponent extends React.Component {
shouldComponentUpdate(nextProps) {
if (!props.length) {
props = Object.keys(nextProps);
}
for (let i = 0, l = props.length; i < l; i++) {
if (!is(nextProps[props[i]], this.props[props[i]])) {
return true;
}
}
return false;
}
render() {
return React.createElement(Component, assign({},
this.props,
this.state
));
}
}
The general usage of the decorator would be #pure(params).
params can contain the name of the props or can be empty. In the decorator you see the ...props as a parameter. This is where the params are passed in.
The parameter Component of the inner function gets the React Component passed in, on which you use the decorator.
You can use the decorator in your component as follows:
import React from 'react';
import pure from './pure.js';
#pure('myProp', 'anotherProp')
export default MyComponent extends React.Component {
static propTypes = {
myProp: React.PropTypes.any,
anotherProp: React.PropTypes.any
}
render() {
return <p>I only re-render, when my props changed.</p>;
}
}
What does it do?
The decorator overrides the shouldComponentUpdate method of the component. Everytime the React Component calls its shouldComponentUpdate method, it now uses the one provided in the decorator.
The decorator itself compares the props of the Component to the next props that it is going to receive. Only if the props change, the component will update.
This is nice, because it prevents unnecessary rendering - that's great for performance!
You see, decorators are basically functions that take parameters (such as the React Component) and modify them in order to make code reusable. It takes a bit of getting used to, but its no rocket science. :-)
If there are any more questions, please feel free to ask!