A simple classification of components
- Functional components:Functional components apply to
Simple components
We can simply assume that we only need to present the data according to the props passed inYou don't need to involve state
Components of state operations are classified as simple components
// 1. Create functional components
function Demo() {
console.log(this) // 这里的this是undefined
return <h1>Components defined with functions apply to simple component definitions</h1>
}
// 2. Render the component to the page
ReactDOM.render(<Demo/>.document.getElementById('test'))
Copy the code
Since JSX is translated by Babel, functions turn on strict mode by default, so this will be undefined in functional components What happens when you call the render function to render the function component to the page?
- React parse component labels and find corresponding components (error if not found)
- Discovering that the component is defined using a function, which is then called to turn the returned virtual DOM into the real DOM and render it on the page
- Types of components:Class components apply to
Complex components
We can simply consider that components that need to involve complex operations such as data presentation and interaction are classified as complex components
// 1. Create class components
class Demo extends React.Component {
render() {
console.log(this)
return <h1>Class components apply to the definition of complex components</h1>}}// 2. Render the class component to the page
ReactDOM.render(<Demo/>.document.getElementById('test'))
Copy the code
Class component this is the instance object of the class component What happens when you call the Render function to render the class component to the page?
- React parse component labels and find corresponding components (error if not found)
- Find the class defined on the component, then new out the instance of that class, and invoke the Render method on the prototype through that instance
- Turn the virtual DOM returned by the Render method into a real DOM and render it on the page
Three properties of a component
- state
Function components do not have their own this, so they cannot access the state property. In general, function components are called stateless components. We are not talking here about the use of state as defined in the Hooks class component
// 1. Create class components
class Weather extends React.Component{
constructor(props) {
super(props)
this.state = {
isHot: false
}
this.changeWeather = this.changeWeather.bind(this)}changeWeather() {
let isHot = this.state.isHot
this.setState({
isHot: !isHot
})
}
render() {
console.log(this);
const {isHot} = this.state
return <h1 onClick={this.changeWeather}>The weather isHot today. 'Hot' : 'cool '}</h1>}}// 2. Render the component to the page
ReactDOM.render(<Weather />.document.getElementById('test'))
Copy the code
- State is called
state
, is a componentInternal data
, we can construct methods inconstructor
InInitialize the
And then used in the corresponding JSXthis.state
Access, and modify throughsetState
Method is dynamically modified becauseDirect changes do not trigger Render to reproduce
- Notice that the callback function for the click event was performed in constructor
This points to the modification
The callback function in the bind click event does not actually get this, so why does the render method get this? This was actually pointed out in the previous article, thisThe Render method is called on the prototype object of the class through the instance object of the class
So here’s theThis will point to an instance of the class
Object, while the click event binding method is acted asThe event callback is called directly, not by instance, and strict mode is turned on by default, so this is undefined
, so you need to modify this to get an instance of the class
We can omit this from development without constructor, as there are abbreviations
// 1. Create class components
class Weather extends React.Component{
state = {
isHot: false
}
changeWeather = () = > {
let isHot = this.state.isHot
this.setState({
isHot: !isHot
})
}
render() {
console.log(this);
const {isHot} = this.state
return <h1 onClick={this.changeWeather}>The weather isHot today. 'Hot' : 'cool '}</h1>}}// 2. Render the component to the page
ReactDOM.render(<Weather />.document.getElementById('test'))
Copy the code
Class attributes can be defined directly through assignment statements
The state property is initialized
Can be used directly within a classAssignment statement
Define attributes- We know that the arrow function does not have its own this, but if we use this inside the arrow function, we will use this from the outer function as this in the arrow function, so
Custom methods
Can pass through the classAssignment statement + arrow function
Method to define
- props
Prop is an attribute of the component itself. If a prop is an attribute of the component, the props can be used to access the props. In the class component, the instance object of the class is bound to the props property, so we can access the props directly. The property data will be passed as parameters, which we can access directly using the props function parameter. In addition, if there is a lot of data and you need to batch pass the data, you can use the expansion operator on the label to pass the data. Note that: In JS, the expansion operator can not operate on objects directly, but can use the literal form of objects to perform assignment deconstruction. Babel and React are needed to expand objects on labels
// Functional components
function Person(props) {
const {name, age} = props
return (
<ul>
<li>Name: {name}</li>
<li>Age: {age}</li>
</ul>)}/ / class components
class Person extends React.Component{
render() {
const {name, age} = this.props
return (
<ul>
<li>Name: {name}</li>
<li>Age: {age}</li>
</ul>
)
}
}
ReactDOM.render(<Person name="tom" age="19"/>.document.getElementById('test'))
const person = {
name: 'tom'.age: 19
}
ReactDOM.render(<Person {. person} / >.document.getElementById('test1'))
Copy the code
Limit the props passed: Prop types. Js is used to limit props, and global properties are added to propTypes. There are two properties PropTypes on the component that limit data to be passed. DefaultProps specifies the default value for passing data (case sensitive)
Person.propTypes = {
// Restrict the name attribute type to String and must be passed
name: PropTypes.string.isRequired
}
Person.defaultProps = {
// If the ADDR attribute is not passed, the default value is displayed
addr: 'the earth'
}
Copy the code
Restrictions on props in a class component can be abbreviated with the static keyword
static propTypes = {
// Restrict the name attribute type to String and must be passed
name: PropTypes.string.isRequired
}
static defaultProps = {
// If the ADDR attribute is not passed, the default value is displayed
addr: 'the earth'
}
Copy the code
- refs
The ref attribute is used to uniquely bind the tag, and this. Refs is used to retrieve the binding node from the class component. React advises against overusing refs
- String binding form (
It is likely to be abandoned in a way that is not efficient
)
class Demo extends React.Component{
// Click the button to display the data
showData = () = > {
const {input1} = this.refs
alert(input1.value)
}
// Lose focus display data
showData2 = () = > {
const { input2 } = this.refs
alert(input2.value)
}
render() {
return (
<div>
<input ref="input1" type="text" placeholder="Click the button to prompt data" />
<button onClick={this.showData}>Am I</button>
<input ref="input2" onBlur={this.showData2} type="text" placeholder="Lost focus prompt data"/>
</div>
)
}
}
ReactDOM.render(<Demo />.document.getElementById('test1'))
Copy the code
- Callback function form
class Demo extends React.Component{
// Click the button to display the data
showData = () = > {
const {input1} = this
alert(input1.value)
}
// Lose focus display data
showData2 = () = > {
const { input2 } = this
alert(input2.value)
}
/ / save the input
saveInput = node= > {
this.input2 = node
}
render() {
return (
<div>{/** callback is called twice during data update **/}<input ref={node= >This. input1 = node} type="text" placeholder=" placeholder "/><button onClick={this.showData}>Am I</button>{/* Write the function as a class binding function to avoid the update call twice */}<input ref={this.saveInput} onBlur={this.showData2} type="text" placeholder="Lost focus prompt data"/>
</div>
)
}
}
ReactDOM.render(<Demo />.document.getElementById('test1'))
Copy the code
The arguments in the callback function are the bound nodes. If you use the inline function binding, the callback function will fire twice when using setState to update the data. If you use the class binding, you can avoid this problem, but the official documentation states that this problem is irrelevant
- CreateRef form
You can call React. CreateRef to generate a container that stores nodes identified by ref (the container can store only one node and is an overridden relationship) and then access the node through the current property
class Demo extends React.Component{
myRef = React.createRef()
myRef2 = React.createRef()
// Click the button to display the data
showData = () = > {
alert(this.myRef.current.value)
}
// Lose focus display data
showData2 = () = > {
alert(this.myRef2.current.value)
}
render() {
return (
<div>
<input ref={this.myRef} type="text" placeholder="Click the button to prompt data" />
<button onClick={this.showData}>Am I</button>
<input ref={this.myRef2} onBlur={this.showData2} type="text" placeholder="Lost focus prompt data"/>
</div>
)
}
}
ReactDOM.render(<Demo />.document.getElementById('test1'))
Copy the code
In order not to overuse ref, you can also get the DOM element object where the event occurred via event.target
class Demo extends React.Component{
// Lose focus display data
showData2 = (event) = > {
alert(event.target.value)
}
render() {
return (
<div>
<input onBlur={this.showData2} type="text" placeholder="Lost focus prompt data"/>
</div>
)
}
}
ReactDOM.render(<Demo />.document.getElementById('test1'))
Copy the code
Have noticed the JSX binding way with native dom events binding way very like but it is different (case), in order to better compatibility, actually React is using a custom event (synthetic), rather than the native dom events, and in order to more efficient, the React adopted the entrusted to handle events (entrusted to the outermost element)