Undertake the above
<body> <div id="test1"></div> <div id="test2"></div> <!-- Import core library --> <script src="../js/react.development.js"></script> <!-- expanded memory bank --> <script src="../js/react-dom.development.js"></script> <!-- transformation jsx Turn into js --> <script src="../js/babel.min.js"></script> <script type="text/babel"> class Person extends React.Component { render() { console.log("this", this); const { name, sex, age } = this.props; return ( <ul> <li>full name:{name}</li> <li>Gender:{sex}</li> <li>Age:{age + 1}</li> </ul> ); } } const p = { name: "tom", sex: "male", age: 1 }; ReactDOM.render(<Person name="jerry" age="19" sex="male" />,document.getElementById("test1")); ReactDOM.render(<Person {...p} />, document.getElementById("test2")); </script> </body>
Now realize a small demand, and the displayed age is 1 year older than the actual age.
Relatively simple, that is, age+1
<script type="text/babel"> class Person extends React.Component { render() { const { name, sex, age } = this.props; return ( <ul> <li>full name:{name}</li> <li>Gender:{sex}</li> <li>Age:{age + 1}</li> </ul> ); } } const p = { name: "tom", sex: "male", age: 18 }; ReactDOM.render(<Person name="jerry" age="19" sex="male" />,document.getElementById("test1")); ReactDOM.render(<Person {...p} />, document.getElementById("test2")); </script>
After printing, you will find
jerry's age is 191 and tom's is normal 19.
This is because tom's age is of type Number and jerry's age is of type String.
At this time, when we change jerry's age to Number type, a syntax error occurs.
When we want to pass the value of Number type, we should write it as {19}. This is because the data type can be mentioned in the js event, which involves the judgment of data type
const p = { name: "tom", sex: "male", age: 18 }; ReactDOM.render(<Person name="jerry" age={19} sex="male"/>,document.getElementById("test1")); ReactDOM.render(<Person {...p} />, document.getElementById("test2"));
At this time, we think about a problem, {19} is written in the Person component defined by ourselves,
We clearly know that the requirement is to add 1 to the age, so it is written like this. However, when others meet similar requirements and use the components we write for development, we do not know whether we correctly write the value {19} of Number type, so it is possible to write "19" of String type, resulting in incorrect data.
Therefore, we need to limit the type of tag attributes passed by the Person component. Based on the above, expand small needs. 1. When gender is not transmitted, male is displayed by default. 2. Name is required.
Sort it out a little:
- Type limit the value passed by props.
- Default value of a property
- Required
How to limit? That is to limit the props in the component instance object, that is, the passed value
Who new creates the component instance object? It is the person component defined by us. Each time we write a person component, react will help us create a new component instance. All the passed contents are included in the component instance props.
Let's start with a piece of pseudo code and imagine that we are the designer of props. How should we limit it
Person.Attribute rule = { name:'Required, string' }; const p = { name: "tom", sex: "male", age: 18 };
In the react requirement, an attribute is added to the react instance person itself. The attribute name is propTypes. prop means attribute and type means type. When adding propTypes to person and adding specific rules, react can help you limit.
Person.propTypes = { name:React.PropTypes };
Don't make a mistake. The two properties are very similar. PropTypes belongs to the built-in property of React.
Person.propTypes = { name:React.PropTypes.string };
React.PropTypes.string adds attribute restrictions (rules) to name, but when we open the console, we find the error message Uncaught TypeError: Cannot read properties of undefined (reading 'string'). The simple understanding is that we can't read sting on undefined, so there is a problem on the left side of. String.
That is, PropTypes are undefined. It should be explained here that in React15.xxx version, React maintained this attribute all the time, and then abandoned this attribute (because it is bound to React and is not a required attribute, resulting in React redundancy).
A library support is required
Person.propTypes = { name: PropTypes.string, }; const p = { name: "jeery", sex: "male", age: 17 }; ReactDOM.render(<Person {...p} />, document.getElementById("test1")); ReactDOM.render( <Person name="tom" sex="female" age={18} />, document.getElementById("test2") );
The page is displayed normally
Now let's experiment by changing tom's name to {10}
ReactDOM.render(<Person name={10} sex="female" age={18} />,document.getElementById("test2"));
Open the console
The error information is as follows:
react.development.js:2726 Warning: Failed prop type: Invalid prop name of type number supplied to Person, expected string.
This means that I want name to be a string, but I get a number. This console will obviously report an error and prompt the developer to pass the attribute correctly, which completes the first small requirement: type limit the value passed by props.
Next, let's look at the third required item. PropTypes provides an isRequired attribute to limit the default value of props. An example is as follows
Person.propTypes = { name: PropTypes.string.isRequired, };
The console prints as follows
Warning: Failed prop type: The prop name is marked as required in Person, but its value is undefined.
The name was marked as required, but an undefined was passed.
This solves the third small requirement, which is required. Next, let's look at the remaining small requirements, the default value of an attribute, which involves another attribute, defaultProps, mounted on the Person instance.
Person.propTypes = { name: PropTypes.string.isRequired, }; Person.defaultProps = { sex:'female' } const p = { name: "jeery", sex: "male", age: 17 }; ReactDOM.render(<Person {...p} />, document.getElementById("test1")); ReactDOM.render(<Person name='tom' age={18} />,document.getElementById("test2"));
Let's take another look. Age is of type Number and is not required. In this case, I remove age={18}
Person.propTypes = { name: PropTypes.string.isRequired, sex:PropTypes.string, age:PropTypes.number }; Person.defaultProps = { sex:'female' } const p = { name: "jeery", sex: "male", age: 17 }; ReactDOM.render(<Person {...p} />, document.getElementById("test1")); ReactDOM.render(<Person name='tom' age={18} />,document.getElementById("test2"));
You'll find the console report
that is because
So just give a default value and add some comments
// The specified attribute type and setting are required Person.propTypes = { name: PropTypes.string.isRequired, sex: PropTypes.string, age: PropTypes.number, }; // Set default properties Person.defaultProps = { sex: "female", age: 18, };
In addition, there is a note that we can add some content, such as adding a speaking method and making a restriction. What we think of is function
Person.propTypes = { name: PropTypes.string.isRequired, sex: PropTypes.string, age: PropTypes.number, speak: PropTypes.function }; // Set default properties Person.defaultProps = { sex: "female", age: 18, }; const p = { name: "jeery", sex: "male", age: 17 }; function speak() { console.log("I spoke"); } ReactDOM.render(<Person {...p} />, document.getElementById("test1")); ReactDOM.render(<Person name="tom" speak={speak} />, document.getElementById("test2"));
Open the console
Failed prop type: Person: prop type speak is invalid; it must be a function, usually from the prop-types package, but received undefined.
The meaning here is that speak must be a function, but it is undefined. This is because funciton is not written correctly, as follows
Person.propTypes = { name: PropTypes.string.isRequired, sex: PropTypes.string, age: PropTypes.number, speak: PropTypes.function };
String and number are not capitalized because they avoid conflicts with the built-in string. Function is the keyword that defines the function. The correct way to write it is func