Component data mounting method
Properties (props)
Props is normally imported from the outside, and can also be initialized in some ways inside the component. The properties cannot be changed by the component itself, but you can import new props by actively re rendering the parent component props
If you need more tutorials, just scan the code on wechat
👆👆👆
Don't forget to scan the code to get the information [HD Java learning roadmap]
And [full set of learning videos and supporting materials of various disciplines]
Attributes describe properties and characteristics, and components cannot change them at will.
The previous component code contains the simple use of props. Generally speaking, when using a component, you can put parameters in the attributes of the tag, and all attributes will be used as components props The key value of the object. Components created through the arrow function need to receive props through the parameters of the function:
import React, { Component, Fragment } from 'react' import ReactDOM from 'react-dom' class Title extends Component { render () { return ( <h1>Welcome to{this.props.name}The world of</h1> ) } } const Content = (props) => { return ( <p>{props.name}Is a build UI Library of</p> ) } class App extends Component { render () { return ( <Fragment> <Title name="React" /> <Content name="React.js" /> </Fragment> ) } } ReactDOM.render( <App/>, document.getElementById('root') )
Set default props for components
import React, { Component, Fragment } from 'react' import ReactDOM from 'react-dom' class Title extends Component { // For the component created using class, write the static method directly here to create defaultProps static defaultProps = { name: 'React' } render () { return ( <h1>Welcome to{this.props.name}The world of</h1> ) } } const Content = (props) => { return ( <p>{props.name}Is a build UI Library of</p> ) } // For a component created using the arrow function, you need to write the defaultProps attribute directly on this component Content.defaultProps = { name: 'React.js' } class App extends Component { render () { return ( <Fragment> {/* Since defaultProps is set, it can operate normally without passing props. If passed, the value of defaultProps will be overwritten */} <Title /> <Content /> </Fragment> ) } } ReactDOM.render( <App/>, document.getElementById('root') )
props.children
We know that when using components, they can be nested. To use nested structures in custom components, you need to use props.children . In practical work, we need to write components in this way almost every day.
import React, { Component, Fragment } from 'react' import ReactDOM from 'react-dom' class Title extends Component { render () { return ( <h1>Welcome to{this.props.children}The world of</h1> ) } } const Content = (props) => { return ( <p>{props.children}</p> ) } class App extends Component { render () { return ( <Fragment> <Title>React</Title> <Content><i>React.js</i>Is a build UI Library of</Content> </Fragment> ) } } ReactDOM.render( <App/>, document.getElementById('root') )
Check props using prop types
React is actually born to build large-scale applications. In a large-scale application, you don't know what parameters will be passed in when others use the components you write. It may cause the application to fail to run, but no error will be reported. In order to solve this problem, react provides a mechanism so that the person who writes the component can set parameter check for the props of the component, which needs to be installed and used prop-types:
$ npm i prop-types -S
Status (state)
Status is the data that the component describes a certain display situation. It is set and changed by the component itself, that is, it is maintained by the component itself. The purpose of using status is to make the display of components different in different states (self-management)
Define state
The first way
import React, { Component } from 'react' import ReactDOM from 'react-dom' class App extends Component { state = { name: 'React', isLiked: false } render () { return ( <div> <h1>Welcome to{this.state.name}The world of</h1> <button> { this.state.isLiked ? '❤️cancel' : ' Collection' } </button> </div> ) } } ReactDOM.render( <App/>, document.getElementById('root') )
Another way (recommended)
import React, { Component } from 'react' import ReactDOM from 'react-dom' class App extends Component { constructor() { super() this.state = { name: 'React', isLiked: false } } render () { return ( <div> <h1>Welcome to{this.state.name}The world of</h1> <button> { this.state.isLiked ? '❤️cancel' : ' Collection' } </button> </div> ) } } ReactDOM.render( <App/>, document.getElementById('root') )
this.props and this.state are pure js objects. In vue, the data property is processed by Object.defineProperty. Changing the data of {data will trigger the getter and setter of the data, but such processing is not done in react. If it is changed directly, react cannot know. Therefore, a special method to change the state, setState, needs to be used.
setState
isLiked Stored in the instance state Object, the name of the component render Function, according to the component's state The isliked in the displays the cancelled or favorite content differently. Here you are button Added click event monitoring.
import React, { Component } from 'react' import ReactDOM from 'react-dom' class App extends Component { constructor() { super() this.state = { name: 'React', isLiked: false } } handleBtnClick = () => { this.setState({ isLiked: !this.state.isLiked }) } render () { return ( <div> <h1>Welcome to{this.state.name}The world of</h1> <button onClick={this.handleBtnClick}> { this.state.isLiked ? '❤️cancel' : ' Collection' } </button> </div> ) } } ReactDOM.render( <App/>, document.getElementById('root') )
setState has two parameters
The first parameter can be an object or a method return object. We call this parameter updater
- Parameters are objects
this.setState({ isLiked: !this.state.isLiked })
- Parameters are methods
this.setState((prevState, props) => { return { isLiked: !prevState.isLiked } })
Note that this method receives two parameters, the first is the last state and the second is props
setState is asynchronous, so if you want to get the latest state, you can't get it. You have the second parameter, which is an optional callback function
this.setState((prevState, props) => { return { isLiked: !prevState.isLiked } }, () => { console.log('In callback',this.state.isLiked) }) console.log('setState External',this.state.isLiked)
Attribute vs status
Similarities:
They are all pure js objects and will trigger the render update. They are deterministic (the status / attributes are the same and the results are the same)
difference:
- The property can be obtained from the parent component, and the status cannot be changed
- The property can be modified by the parent component, and the status cannot be changed
- Property can set default values internally, and the status can also be
- The attribute is not modified inside the component, and the status needs to be changed
- Property can set the initial value of sub components, but the status cannot
- Property can modify the value of sub components, but the status cannot
state Its main function is to save, control and modify its own variable state. state Initialization within a component can be modified by the component itself, but it cannot be accessed or modified externally. You can think state It is a local data source that can only be controlled by the component itself. state The status can be through Update this.setState method, setState This will cause the component to be re rendered.
props The main function of is to allow the parent component using the component to pass in parameters to configure the component. It is an external configuration parameter, which cannot be controlled or modified inside the component. Unless an external component actively passes in a new Props, otherwise the component Props will always remain the same.
If you don't know state and props Remember a simple rule: use as little as possible State, multipurpose props.
No, state The component with state is called a stateless component, and the component with state set is called a stateful component. Because the state will bring the complexity of management, we write as many stateless components as possible and as few stateful components as possible. This will not only reduce the difficulty of code maintenance, but also enhance the reusability of components to a certain extent.
##State promotion
If multiple components share one data, the data is managed in a common parent component
Controlled and uncontrolled components
Whether the data rendering of the React component is completely controlled by the props passed by the caller is a controlled component, otherwise it is an uncontrolled component.
Render data
- conditional rendering
{ condition ? '❤️cancel' : ' Collection' }
- List rendering
// data const people = [{ id: 1, name: 'Leo', age: 35 }, { id: 2, name: 'XiaoMing', age: 16 }] // Render list { people.map(person => { return ( <dl key={person.id}> <dt>{person.name}</dt> <dd>age: {person.age}</dd> </dl> ) }) }
The efficiency of React depends on the so-called virtual DOM, and try not to touch the dom. There is a problem with list elements: elements may change position in a list. To achieve this operation, you only need to exchange the DOM position, but React doesn't know that we just changed the position of the element, so it will re render the next two elements (and then execute virtual DOM), which will greatly increase the DOM operation. However, if you add a unique identifier to each element, React can know that the two elements only exchange positions. This identifier is the key and this key Must be a unique identifier for each element
- dangerouslySetHTML
For the content created by rich text, the data obtained in the background is as follows:
content = "<p>React.js Is a build UI Library of</p>"
For security reasons, the contents of all expressions in React will be escaped. If you enter directly, the label will be regarded as text. At this point, we need to use the dangerouslySetHTML attribute, which allows us to dynamically set innerHTML
import React, { Component } from 'react' import ReactDOM from 'react-dom' class App extends Component { constructor() { super() this.state = { content : "<p>React.js Is a build UI Library of</p>" } } render () { return ( <div // Notice that here are two underscores__ html dangerouslySetInnerHTML={{__html: this.state.content}} /> ) } } ReactDOM.render( <App/>, document.getElementById('root') )
event processing
Binding event
Bind an event in the way of on + event name. Note that this is different from the native event. The native event is all lowercase onClick, and the event in React is hump onClick. The event in React is not a native event, but a composite event.
Writing of event handler
- Write the arrow function in the line directly in render (not recommended)
- Define a method within the component using the arrow function (recommended)
- Directly define a method of non arrow function in the component, and then directly use onClick={this.handleClick.bind(this)} in render (not recommended)
- Directly define a method of non arrow function in the component, and then bind (this) in the constructor (recommended)
Event object
Like normal browsers, the event handler is automatically passed in a event Object, which is similar to a normal browser event The methods and properties contained in the object are basically the same. The difference is in React event The object is not provided by the browser, but built internally. It also has common methods such as event.stopPropagation and event.preventDefault
Parameter passing of event
- There is a layer of arrow function outside the place where the method is called in render
- this.handleEvent.bind(this, parameter) is passed in render
- Pass through event
- It is recommended to make a sub component, define a method in the parent component, pass it to the sub component through props, and then call it through this.props.method in the sub component
##Process user input
import React, { Component } from 'react' import ReactDOM from 'react-dom' class App extends Component { constructor() { super() this.state = { xing: '', ming: '' } } handleInputChange = (e) => { this.setState({ [e.target.name]: e.target.value }) } render () { const { xing, ming } = this.state return ( <div> <label> <span>lastname:</span> <input type="text" name="xing" value={xing} onChange={this.handleInputChange} /> </label> <label> <span>name:</span> <input type="text" name="ming" value={ming} onChange={this.handleInputChange} /> </label> <p>Welcome: {xing}{ming}</p> </div> ) } } ReactDOM.render( <App/>, document.getElementById('root') )
If you need more tutorials, just scan the code on wechat
👆👆👆
Don't forget to scan the code to get the information [HD Java learning roadmap]
And [full set of learning videos and supporting materials of various disciplines]