1、类组件
1、参数的传递形式:
1)、父组件通过 属性=值 的形式来传递给子组件数据
2)、子组件通过 props 参数获取父组件传递过来的数据;
import React, { Component } from 'react'
class ChildCpn extends Component {
constructor(props) {
super(props)
// this.props = props;
}
render() {
const { name, age, height } = this.props;
return (<div>
<h2>{"子组件展示数据" + name + age + height}</h2>
</div>)
}
}
export class App extends Component {
render() {
console.log('ChildCpn render')
return (
<div>
<ChildCpn name="age" age="18" height="1.88" />
</div>
)
}
}
export default App
2、props传递源码分析
super(props)、将props传递给父组件
// ReactBaesClasses.js 20行
/**
* Base class helpers for the updating state of a component.
*/
function Component(props, context, updater) {
this.props = props;
this.context = context;
// If a component has string refs, we will assign a different object later.
this.refs = emptyObject;
// We initialize the default updater but the real one gets injected by the
// renderer.
this.updater = updater || ReactNoopUpdateQueue;
}
3、转换为ES5分析super的本质
es6console.com
// es6
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
running () {
console.log('running');
}
}
class Student extends Person {
constructor(name, age, son) {
super(name, age);
this.son = son;
}
}
// es5
...
var Person = function () {
function Person(name, age) {
_classCallCheck(this, Person);
this.name = name;
this.age = age;
}
_createClass(Person, [{
key: 'running',
value: function running() {
console.log('running');
}
}]);
return Person;
}();
var Student = function (_Person) {
_inherits(Student, _Person);
function Student(name, age, son) {
_classCallCheck(this, Student);
// 将Student对象this绑定到Person对象中
var _this = _possibleConstructorReturn(this, (Student.__proto__ || Object.getPrototypeOf(Student)).call(this, name, age));
_this.son = son;
return _this;
}
return Student;
}(Person); // 在ES5中是将Person函数作为参数传递给Student
4、props在组件中的赋值时机
import React, { Component } from 'react'
class ChildCpn extends Component {
constructor(props) {
super()
console.log(this.props); // undefined
}
render() {
console.log(this.props) // {name: 'age', age: '18', height: '1.88'}
const { name, age, height } = this.props;
return (<div>
<h2>{"子组件展示数据" + name + age + height}</h2>
</div>)
}
}
export default class App extends Component {
render() {
console.log('ChildCpn render')
return (
<div>
<ChildCpn name="age" age="18" height="1.88" />
</div>
)
}
}
通过源码分析
// ReactPartialRenderer.js
function resolve( // line 414
child: mixed,
context: Object,
threadID: ThreadID,
): {|
child: mixed,
context: Object,
|} {
...
function processChild(element, Component) { // line 436
...
let inst;
if (isClass) { // line 466
inst = new Component(element.props, publicContext, updater);
...
}
...
// line 570
inst.props = element.props; // 传递props
inst.context = publicContext;
inst.updater = updater;
...
}
}
2、函数式组件
import React, { Component } from 'react'
// 通过function的参数传递props
function ChildCpn(props) {
const { name, age, height } = props;
return (<div>
<h2>{"子组件展示数据" + name + age + height}</h2>
</div>)
}
export default class App extends Component {
render() {
console.log('ChildCpn render')
return (
<div>
<ChildCpn name="age" age="18" height="1.88" />
</div>
)
}
}
3、组件参数验证
如果项目中默认继承了Flow或者TypeScript,那么直接就可以进行类型验证
但即使你不使用这些扩展,也可以通过React的内置 prop-types 库来进行参数验证
import React, { Component } from 'react'
import PropTypes from 'prop-types';
function ChildCpn(props) {
const { name, age, height } = props;
return (<div>
<h2>{"子组件展示数据" + name + age + height}</h2>
</div>)
}
ChildCpn.propTypes = {
name: PropTypes.string.isRequired,
age: PropTypes.number,
height: PropTypes.number
}
// 可以通过配置特定的 defaultProps 属性来定义 props 的默认值
ChildCpn.defaultProps = {
name: "小名"
}
class ChildCpn2 extends Component {
// es6中class fields
static propTypes = {
name: PropTypes.string.isRequired,
age: PropTypes.number,
height: PropTypes.number
}
static defaultProps = {
name: 'stranger'
}
render() {
const { name, age, height } = props;
return (<div>
<h2>{"子组件展示数据" + name + age + height}</h2>
</div>)
}
}
export default class App extends Component {
render() {
console.log('04_04_父传子通讯-属性验证');
return (
<div>
<ChildCpn age="18" height="1.88" />
<ChildCpn2 age="18" height="1.88" />
</div>
)
}
}
4、子组件传递父组件数据
import React, { Component } from 'react'
class CounterBtn extends Component {
render() {
const { increatment } = this.props;
return (
<div>
<button onClick={increatment}>+1</button>
</div>
)
}
}
export default class App extends Component {
constructor() {
super()
this.state = {
counter: 0
}
}
render() {
return (
<div>
<h2>当前计数:{this.state.counter}</h2>
<button onClick={e => this.increatment()}>+1</button>
<CounterBtn increatment={e => this.increatment()} />
</div>
)
}
increatment() {
this.setState({
counter: this.state.counter + 1
})
}
}
网友评论