import React from "react";
const person = (props) => {
return (
<div>
<p> onClick={props.click} I'm {props.name} and I am {props.age} years old!</p>
<p>{props.children}</p> // anything between the parent's opening and closing tag
<input type="text" onChange={props.changed} value={props.name} /> // two way data binding
</div>
);
};
export default person;
Using arrow functions in the callback - Since callback is created each time the button renders. If this callback is passed as a prop to lower components, those components might do an extra re-rendering, which will cause performance problems.
// must wrap the code you want to test using high order components
import React, { Component } from 'react';
class ErrorBoundary extends Component {
state = {
hasError: false,
errorMessage: ''
}
static getDerivedStateFromError(error) {
// update state so the next render will show the fallback UI.
return { hasError: true };
}
componentDidCatch = (error, info) => {
// you can also log the error to an error reporting service
// logErrorToMyService(error, info);
this.setState({ hasError: true, errorMessage: error });
}
render() {
if (this.state.hasError) {
// you can render any custom fallback UI
return <h1>{this.state.errorMessage}</h1>;
}
return this.props.children;
}
}
export default ErrorBoundary;
Three ways using Higher Order Component
// This one just do wrap other component
const aux = props => props.children;
export default aux;
// This one just add styling to the children component
import React from 'react';
// const withClass = props => (
// <div className={props.classes}>
// {props.children}
// </div>
// );
const withClass = (WrappedComponent, className) => {
return props => (
<div className={className}>
// getting the props from the child compoent
<WrappedComponent {...props}/>
</div>
);
}
export default withClass;
// This is the built-in way that works same as the first one
import React, {Fragment} from 'react';
<Fragment>
// some content
</Fragment>
Better way to use setState() callback
What is the purpose of the callback function as an argument of setState()?
setState may be called in async function
So you cannot rely on this. If the above call was made inside a async function this will refer to state of component at that point of time but we expected this to refer to property inside state at time setState calling or beginning of async task. Ensuring reliability that nextState would not be corrupted.
// the better way to update the state when you are depending on old state
// Since setState updates the state asynchronously
this.setState((state, props) => {
return {
counter: state.counter + props.increment
};
});
In HTML, form elements such as <input>, <textarea>, and <select> typically maintain their own state and update it based on user input. In React, mutable state is typically kept in the state property of components, and only updated with setState().
We can combine the two by making the React state be the "single source of truth". Then the React component that renders a form also controls what happens in that form on subsequent user input. An input form element whose value is controlled by React in this way is called a "controlled component".
React.lazy takes a function that must call a dynamic import(). This must return a Promise which resolves to a module with a default export containing a React component.
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import classes from './Person.css';
class Person extends Component {
constructor(props) {
super(props);
this.inputElementRef = React.createRef();
}
// creates a Context object. When React renders a component
// that subscribes to this Context object it will read the
// current context value from the closest matching Provider
// above it in the tree.
const AuthContext = React.createContext({
authenticated: false,
login: () => {}
});
static contextType = AuthContext;
componentDidMount() {
// this.inputElement.focus();
this.inputElementRef.current.focus();
}
render() {
return (
<React.Fragment>
// <AuthContext.Consumer>
// {context =>
// context.authenticated ? <p>Authenticated</p> : <p>Please log in</p>}
// </AuthContext.Consumer>
{this.context.authenticated ? (
<p>Authenticated!</p>
) : (
<p>Please log in</p>
)}
<p>{this.props.children}</p>
<input
// ref={(inputEl) => {this.inputElement = inputEl}}
ref={this.inputElementRef}
type="text"
onChange={this.props.changed}
value={this.props.name}
/>
</React.Fragment>
);
}
}
Person.propTypes = {
click: PropTypes.func,
name: PropTypes.string,
age: PropTypes.number,
changed: PropTypes.func
};
export default Person;
// code in the parent file
<AuthContext.Provider
value={{
authenticated: this.state.authenticated,
login: this.loginHandler
}}
>
<Person/>
</AuthContext.Provider>
forwardRef
// You can now get a ref directly to the DOM button
const ref = React.createRef();
<FancyButton ref={ref}>Click me!</FancyButton>;
const FancyButton = React.forwardRef((props, ref) => (
// ref.current now point to the <button> DOM node
<button ref={ref} {...props}>
{props.children}
</button>
));
Portals
render() {
// React does not create a new div. It renders the children into domNode.
// domNode is any valid DOM node, regardless of its location in the DOM.
return ReactDOM.createPortal(
this.props.children,=
domNode
);
}
pass a parameter to an event handler or callback
import React from "react";
class App extends React.Component {
call(message,event) {
alert(message);
}
render() {
return (
//Creating a arrow function
<button onClick={(event)=> this.call("Your message",event)}>
Click the button!
</button>
);
}
}
export default App;