This article has participated in the “Digitalstar Project” and won a creative gift package to challenge the creative incentive money.
Today we’ll continue with the basics of React. We’ll look at component-oriented programming, understand the concepts of components (previous article), and use them in general. We’ll also learn about uncontrolled components and controlled components, as well as higher-order functions and Curryization, which you’ll often hear about
1. Basic understanding and use
1.1 Functional Components
// 1. Create functional components
function MyComponent(){
console.log(this); // This is undefined because strict mode is enabled after Babel is compiled
return <h2>I am a component defined with functions (definition for simple components)</h2>
}
// 2. Render the component to the page
ReactDOM.render(<MyComponent/>.document.getElementById('test'))
Copy the code
To perform theReactDOM.render(<MyComponent/>.......
After that, what happened?
- React parses the component tag and finds the MyComponent component.
- The component is found to be defined using a function, which is then called to turn the returned virtual DOM into the real DOM, which is then rendered on the page.
【 supplement 】 Strict mode of this
function sayThis() {
console.log(this)
}
sayThis() // Window {... }
function sayThis2() {
'use strict'
console.log(this)
}
sayThis2() // undefined
Copy the code
So if you don’t have strict mode on, you call the function, and this refers to the window, and this is undefined
1.2 Class components
//1. Create a class component
class MyComponent extends React.Component {
render(){
//render is placed where? -- on the MyComponent prototype object for instance use.
// Who is this in render? <=> MyComponent instance object.
console.log('this in the render:.this);
return <h2>I am a component defined with a class (for the definition of a complex component)</h2>}}//2. Render the component to the page
ReactDOM.render(<MyComponent/>.document.getElementById('test'))
Copy the code
Perform the ReactDOM. Render (< MyComponent / >… After that, what happened?
- React parses the component tag and finds the MyComponent component.
- Discover that the component is defined using a class, and then
new
Gets an instance of the class and calls it to the prototyperender
Methods. - will
render
The returned virtual DOM is converted into the real DOM and rendered on the page.
Notes about classes in ES6
- A constructor in a class is not required to be written; it is only written when an instance is initialized, such as when a specified attribute is added.
- If class A inherits class B, and class A writes constructors, then the constructor of class A
super
Is a must call. - The methods defined in the class are placed on the prototype object of the class for instance to use.
1.3 pay attention to
- Component names must begin with a capital letter
- Virtual DOM elements can have only one root element
- Virtual DOM elements must have closing tags
- Focus on the basic process of rendering a class component tag
- React creates component instance objects internally
- call
render()
Get the virtual DOM and parse it into the real DOM - Inserts inside the specified page element
2. Three core attributes of component instance 1:state
state
2.1 understand
state
Is the most important property of the component object, and the value is the object (which can contain more than onekey-value
The combination of)- Components are called “state machines” by updating the component’s
state
To update the corresponding page display (re-render the component)
2.2 applications
Requirement: Define a component that displays weather information
- The default display is hot or cool
- Click on the text to switch weather
2.2.1 Manual switching version
Class component that initializes state in constructor and reads state in Render with this.state
// 1. Create components
class Weather extends React.Component{
constructor(props) {
super(props)
// Initialization state
this.state = {
isHot: true}}render() {
// Read the state
const {isHot} = this.state
return <h1>The weather isHot today. 'Hot ':' cool '}</h1>}}// 2. Render the component to the page
ReactDOM.render(<Weather/>.document.getElementById('test'))
Copy the code
Three ways to listen for native JavaScript binding events
<button id="btn1">Button 1</button>
<button id="btn2">Button 2</button>
<button onclick="demo()">Button 3</button>
<script type="text/javascript" >
const btn1 = document.getElementById('btn1')
btn1.addEventListener('click'.() = >{
alert('Button 1 has been clicked')})const btn2 = document.getElementById('btn2')
btn2.onclick = () = >{
alert('Button 2 was clicked')}function demo(){
alert('Button 3 is clicked.')}</script>
Copy the code
The this of a method in a class refers to the problem
Methods defined in class have local strict mode turned on internally by default. When strict mode is turned on, if a function is called directly, this does not refer to window, but undefined
class Person {
constructor(name,age){
this.name = name
this.age = age
}
study(){
// Where does the study method go? Class on a prototype object for instance use
// When a study is called from a Person instance, this in the study is the Person instance
console.log(this); }}const p1 = new Person('tom'.18)
p1.study() // Call the study method Person via the instance
const x = p1.study
x() // Call undefined directly
Copy the code
2.2.2 Click switch version
// 1. Create components
class Weather extends React.Component {
// How many times is the constructor called? -- - 1
constructor(props){
console.log('constructor');
super(props)
// Initialization state
this.state = {isHot:false.wind:'the wind'}
// Resolve this pointing problem in changeWeather
this.changeWeather = this.changeWeather.bind(this)}// render how many times? ———— 1+n times 1 is the initialization time and n is the number of status updates
render(){
console.log('render');
// Read the state
const {isHot,wind} = this.state
return <h1 onClick={this.changeWeather}>The weather isHot today. 'hot' : 'cool '}, {wind}</h1>
}
// How many changeWeather calls? ———— click a few times to tune a few times
changeWeather(){
// Where is changeWeather? ———— Weather's prototype object for example use
// Since changeWeather is called as a callback to onClick, it is not called by instance, but directly
// Methods in the class have local strict mode turned on by default, so this in changeWeather is undefined
console.log('changeWeather');
// Get the old isHot value
const isHot = this.state.isHot
// Important note: The state must be updated with setState, and the update is a merge, not a replacement.
this.setState({isHot:! isHot})// console.log(this);
// Important note: The state cannot be changed directly.
// this.state.isHot = ! IsHot // This is the wrong way to write}}//2. Render the component to the page
ReactDOM.render(<Weather/>.document.getElementById('test'))
Copy the code
2.2.3 Thin code (written like this in actual development)
- Instead of writing a constructor, you can write an assignment statement in the class to initialize the state
- Don’t bind this (assignment statement + arrow function)
// 1. Create components
class Weather extends React.Component{
// Initialization state
state = {isHot:false.wind:'the wind'}
render(){
const {isHot,wind} = this.state
return <h1 onClick={this.changeWeather}>The weather isHot today. 'hot' : 'cool '}, {wind}</h1>
}
// The custom method ———— uses the form of an assignment statement + arrow function
// Not on a prototype, but on an instance
changeWeather = () = > {
const isHot = this.state.isHot
this.setState({isHot:! isHot}) } }// 2. Render the component to the page
ReactDOM.render(<Weather/>.document.getElementById('test'))
Copy the code
Write assignment statements directly in class
Writing an assignment statement directly into a class is equivalent to adding attributes and assigning values to instance objects of the class
2.3 pay attention to
- In the component
render
Method this is the component instance object - Component custom methods
this
forundefined
And how to solve it? A) Forced bindingthis
: by function objectbind()
B) Arrow function + assignment statement - State data
state
Cannot be modified or updated directly - State must pass
setState()
Update, and update is a kind ofmergeNot substitution.
3. Three core attributes of a component instance 2:props
3.1 understand
- Every component object has it
props
Short for properties - All attributes of the component tag are stored in
props
In the
3.2 role
- Changing data is passed from component to component through label properties
- Note: inside the componentDo not modify the
props
The data is read-only
3.3 Try it
// Create a component
class Person extends React.Component{
render() {
return (
<ul>
<li>Name: {this. Props. The name}</li>
<li>Gender: {this. Props. Sex}</li>
<li>Age: {this. Props. Age}</li>
</ul>)}}// Render the component to the page
ReactDOM.render(<Person name="yk" age="18" sex="Male"/>.document.getElementById('test'))
Copy the code
3.4 Usage Guide
3.4.1 Reading an attribute value internally
this.props.name
Copy the code
3.4.2 Extended Attributes: Passes all attributes of the objectprops
Pass (Batch pass tag attributes)
ReactDOM.render(<Person name="yk" age="18" sex="Male"/>.document.getElementById('test'))
Copy the code
const person = {name: 'yk'.age: 18.sex: 'male'}
ReactDOM.render(<Person { . person} / >.document.getElementById('test'))
Copy the code
Expansion operator
let arr1 = [1.3.5.7.9]
let arr2 = [2.4.6.8.10]
// 1. Expand an array
console.log(... arr1);// 1 3 5 7 9
// 2. Join array
let arr3 = [...arr1, ...arr2]
// 3. Use it in functions
function sum(. numbers) {
return numbers.reduce((preValue, currentValue) = > {
return preValue + currentValue
})
}
console.log(sum(1.2.3.4)); / / 10
// 4. Use expansion syntax when constructing literal objects
let person = {
name: 'tom'.age: 18
}
// console.log(... person); // The expansion operator cannot expand the object
console.log({... person})// {name: "tom", age: 18}
letperson2 = { ... person }// You can copy an object
person.name = 'jerry'
console.log(person2); // {name: "tom", age: 18}
console.log(person); // {name: "jerry", age: 18}
// 5. Merge objects
letperson3 = { ... person,name: 'jack'.address: "The earth"
}
console.log(person3); // {name: "jack", age: 18, address: "earth "}
Copy the code
Rule 3.4.3 toprops
Attribute values in the
1. React V15.5 deprecated
Person.propTypes = {
name: React.PropTypes.string.isRequired,
age: React.PropTypes.number
}
Copy the code
2. Second way (new) : Useprop-types
Library import restrictions (need to be introducedprop-types
Library)
<! -- Introduce prop-types to restrict component tag properties -->
<script type="text/javascript" src=".. /js/prop-types.js"></script>
Copy the code
// Restrict the type and necessity of the tag attributes
Person.propTypes = {
name:PropTypes.string.isRequired, // Restrict name to a string
sex:PropTypes.string, // Restrict sex to a string
age:PropTypes.number, // Limit age to a numeric value
speak:PropTypes.func, // restrict speak as a function
}
Copy the code
You can write it inside the class with the static keyword
3.4.4 Default Attribute Values
// Specify the default tag attribute value
Person.defaultProps = {
sex:'male'.// sex The default value is male
age:18 //age The default value is 18
}
Copy the code
You can write it inside the class with the static keyword
3.4.5 Component class constructors
constructor(props){
super(props)
console.log(this.props)// Prints all attributes
}
Copy the code
Whether the constructor acceptsprops
Is passed tosuper
Depends on whether you want to pass through the constructorthis
accessprops
3.5 applications
Requirement: Customize the component used to display a person’s information
- The name must be a string;
- Gender is a string. If gender is not specified, the default value is male
- The age is a string and a number. The default value is 18
// Create a component
class Person extends React.Component{
// Restrict the type and necessity of the tag attributes
static propTypes = {
name:PropTypes.string.isRequired, // Restrict name to a string
sex:PropTypes.string,// Restrict sex to a string
age:PropTypes.number,// Limit age to a numeric value
}
// Specify the default tag attribute value
static defaultProps = {
sex:'male'.//sex The default value is male
age:18 //age The default value is 18
}
render(){
// console.log(this);
const {name,age,sex} = this.props
//props is read-only
//this.props. Name = 'jack' // This line is an error because props is read-only
return (
<ul>
<li>Name: {name}</li>
<li>Gender: {sex}</li>
<li>Age: + 1} {the age</li>
</ul>)}}// Render the component to the page
ReactDOM.render(<Person name="jerry"/>.document.getElementById('test1'))
Copy the code
3.6 Functional Component usageprops
// Create a component
function Person (props){
const {name,age,sex} = props
return (
<ul>
<li>Name: {name}</li>
<li>Gender: {sex}</li>
<li>Age: {age}</li>
</ul>
)
}
Person.propTypes = {
name:PropTypes.string.isRequired, // Restrict name to a string
sex:PropTypes.string, // Restrict sex to a string
age:PropTypes.number, // Limit age to a numeric value
}
// Specify the default tag attribute value
Person.defaultProps = {
sex:'male'.// sex The default value is male
age:18 // age The default value is 18
}
// Render the component to the page
ReactDOM.render(<Person name="jerry"/>.document.getElementById('test1'))
Copy the code
4. Three core attributes of component 3:refs
And event handling
4.1 understand
A label within a component can define a REF attribute to identify itself
4.2 applications
Requirements: User-defined components. The functions are described as follows
- Click the button to prompt for the value in the first input box
- When the second input box loses focus, the value in this input box is prompted
4.3 coding
4.3.1 The value is a stringref
(The new version is not recommended.)
Definition 1.
<input ref="input1"/>
Copy the code
2. Use
this.refs.input1
Copy the code
Example 3.
// Create a component
class Demo extends React.Component{
// Display the data in the left input box
showData = () = >{
const {input1} = this.refs
alert(input1.value)
}
// Display the data in the input box on the right
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}>Click on the data to the left of my tip</button>
<input ref="input2" onBlur={this.showData2} type="text" placeholder="Lost focus prompt data"/>
</div>)}}// Render the component to the page
ReactDOM.render(<Demo />.document.getElementById('test'))
Copy the code
4.3.2 In the form of callbackref
Definition 1.
<input ref={(currentNode) = >{this.input1 = currentNode}} />
Copy the code
Short the
<input ref={ c= > this.input1 = c } />
Copy the code
2. Use
this.input1
Copy the code
Example 3.
// Create a component
class Demo extends React.Component{
// Display the data in the left input box
showData = () = >{
const {input1} = this
alert(input1.value)
}
// Display the data in the input box on the right
showData2 = () = >{
const {input2} = this
alert(input2.value)
}
render(){
return(
<div>
<input ref={ c= >This. input1 = c} type="text" placeholder=" placeholder "/>
<button onClick={this.showData}>Click on the data to the left of my tip</button>
<input onBlur={this.showData2} ref={c= >This. input2 = c} type="text" placeholder=" placeholder "/>
</div>)}}// Render the component to the page
ReactDOM.render(<Demo />.document.getElementById('test'))
Copy the code
4. Callback execution times
Inline callbacks, called once at render time, and class-bound callbacks are executed twice for each update, called once at initial render time
The influence is not big, the daily development is basically usedinlineMake it more convenient
4.3.3 createRef
createref
The container
Definition 1.
// react. createRef returns a container
// This container can store nodes identified by ref. This container is "dedicated"
myRef = React.createRef()
<input ref={this.myRef}/>
Copy the code
2. Use
this.myRef.current
Copy the code
Example 3.
// Create a component
class Demo extends React.Component{
myRef = React.createRef()
myRef2 = React.createRef()
// Display the data in the left input box
showData = () = >{
alert(this.myRef.current.value);
}
// Display the data in the input box on the right
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}>Click on the data to the left of my tip</button>
<input onBlur={this.showData2} ref={this.myRef2} type="text" placeholder="Lost focus prompt data"/>
</div>)}}// Render the component to the page
ReactDOM.render(<Demo />.document.getElementById('test'))
Copy the code
5. Event handling in React
-
Specify event handlers via the onXxx property (case sensitive)
- React uses custom (synthesized) events instead of using native DOM events —- for better compatibility
- React events are handled by event delegation (delegating to the outermost element of the component) —- for efficiency
-
Get the DOM element object where the event occurred via event.target —- Don’t overuse ref
This can be avoided when the element on which the event occurs is an element that requires actionref
// Create a component
class Demo extends React.Component{
// Create ref container
myRef = React.createRef()
// myRef2 = React.createRef()
// Display the data in the left input box
showData = (event) = >{
console.log(event.target);
alert(this.myRef.current.value);
}
// Display the data in the input box on the right
showData2 = (event) = >{
alert(event.target.value);
}
render(){
return(
<div>
<input ref={this.myRef} type="text" placeholder="Click the button to prompt data"/>
<button onClick={this.showData}>Click on the data to the left of my tip</button>
<input onBlur={this.showData2} type="text" placeholder="Lost focus prompt data"/>
</div>)}}// Render the component to the page
ReactDOM.render(<Demo />.document.getElementById('test'))
Copy the code
6. Collect form data
6.1 understand
Component categories that contain forms
- The controlled components
- Uncontrolled component
6.2 applications
Requirements: Define a component that contains a form after entering a user name and password, click login to prompt for input information
6.3 Uncontrolled Components
All input DOM class values in the page are used and fetched in situ
// Create a component
class Login extends React.Component {
handleSubmit = (event) = > {
event.preventDefault() // Block form submission
const {username, password} = this
alert('The user name you entered is${username.value}, your password is:${password.value}`)}render() {
return (
<form action="https://www.baidu.com/" onSubmit={this.handleSubmit}>User name:<input ref={c= >This. username = c} type="text" name="username" /><input ref={c= > this.password = c} type="password" name="password" />
<button>The login</button>
</form>)}}// Render component
ReactDOM.render(<Login />.document.getElementById('test'))
Copy the code
6.4 Controlled Components
The DOM of the class is entered in the page, and as it is entered, the data is stored in a state state from which it can be retrieved when needed (similar to two-way data binding in Vue).
// Create a component
class Login extends React.Component {
// Initialization state
state = {
username: ' '.password: ' '
}
// Save the user name to the status
saveUsername = (event) = > {
this.setState({username: event.target.value})
}
// Save the password to the status
savePassword = (event) = > {
this.setState({password: event.target.value})
}
// Form submission callback
handleSubmit = (event) = > {
event.preventDefault()
const {username, password} = this.state
alert('The user name you entered is${username}, your password is:${password}`)}render() {
return (
<form action="https://www.baidu.com/" onSubmit={this.handleSubmit}>User name:<input onChange={this.saveUsername} type="text" name="username" />Password:<input onChange={this.savePassword} type="password" name="password" />
<button>The login</button>
</form>)}}// Render component
ReactDOM.render(<Login />.document.getElementById('test'))
Copy the code
7. Higher order functions and currization of functions
7.1 Higher-order functions
Higher-order function: A function is higher-order if it conforms to either of the following two specifications.
- If A function takes A function, then A can be called A higher-order function.
- A function can be called A higher-order function if the return value of the call is still A function.
Common higher-order functions are Promise, setTimeout, arr.map(), and so on
7.2 Currization of functions
Corrification of a function: a form of function encoding in which parameters are received multiple times and then processed uniformly by calling a function.
function sum1(a, b, c){
return a + b + c;
}
sum1(1.2.3)
// After currified
function sum(a){
return(b) = >{
return (c) = >{
return a+b+c
}
}
}
sum(1) (2) (3)
Copy the code
Use of higher-order functions and function Currie simplification to abbreviate the code in 6.4
// Create a component
class Login extends React.Component{
// Initialization state
state = {
username:' './ / user name
password:' ' / / password
}
// Save form data to state (higher order function + function currification)
saveFormData = (dataType) = >{
return (event) = >{
this.setState({[dataType]:event.target.value})
}
}
// Form submission callback
handleSubmit = (event) = >{
event.preventDefault() // Block form submission
const {username,password} = this.state
alert('The username you entered is:${username}, your password is:${password}`)}render(){
return(
<form onSubmit={this.handleSubmit}>User name:<input onChange={this.saveFormData('username')} type="text" name="username"/>Password:<input onChange={this.saveFormData('password')} type="password" name="password"/>
<button>The login</button>
</form>)}}// Render component
ReactDOM.render(<Login/>.document.getElementById('test'))
Copy the code
7.4 Implement 7.3 without Kriging
// Save the form data to the state
saveFormData = (dataType,event) = >{
this.setState({[dataType]:event.target.value})
}
render(){
return(
<form onSubmit={this.handleSubmit}>User name:<input onChange={ event= >This.saveformdata ('username',event)} type="text" name="username"/><input onChange={ event= > this.saveFormData('password',event) } type="password" name="password"/>
<button>The login</button>
</form>)}Copy the code