create-element 在处理的时候,遇到一个组件,返回的对象中type就不再是字符串,而是一个函数(类),但是属性还是props中
({ type:Dialog, props:{ lx:1, con:'xxx', children:一个值或者一个数组 } } 首先判断type是什么类型,如果是字符串就创建一个元素标签,如果函数或者类,就把函数执行,把props中的每一项(包含children传递给函数) React.Children.map 基于继承component类创建组件 基于create-element 把jax 转换为一个对象,当react渲染这个对象的时候,遇到type是一个函数或者类,不是直接创建元素,而是先把方法执行: * 如果是函数式声明的组件,就把它当作普通方法执行(方法中的this是undefiend),把函数返回的jsx元素进行渲染 * 如果是类声明式的组件,会把房钱类new它执行,创建类的一个实例(当前本次调用组件就是它的实例)执行constructor之后,会执行this.render(),把render中返回的jsx拿过来渲染,所以 类声明式组件,必须有一个render的方法,方法中需要一个jsx元素 但是不管是哪一种方式,最后都会拿解析出来的props属性对象作为实参给对应的函数或者类创建组件有两种方式"函数式","创建类式"
函数式
简单
能实现的功能也很简单,只是简单的调取和返回jsx而已
ReactDOM.render(<div> /*单闭合*/ <Vote title={xxx}/> /*双闭合*/ <Vote> <p>11111111</p> </Vote> </div>) import React from 'react'; exprot default function Vote(props){ return <div className={'penel panel-default'}> {props.Children} {props.Children.map(props,children,item=>{return item;})} </div> }创建类式
操作相对复杂一些,但是也可以实现更为复杂的业务功能
能够使用生命周期函数操作业务
函数式可以理解为静态组件(组件中的内容调取的时候就已经固定了,很难在修改,而这种类的组件可以基于组件内部的状态来动态更新渲染的内容
import React from 'react'; //ref是react操作DOM的方案 //* 给需要操作的元素设置ref(保持唯一性,否则会冲突覆盖) //* 在实例上挂载了refs属性,他是一个对象,存储了所有设置ref的元素(ref值:元素对象) export default class Vote extends React.Component{ constructor(props){ super(props); //React.Component.call(this)可以把component中的私有实例继承过来,this.props/this.state(this.setState)/this.content/this.refs/this.updater //初始化状态 this.state={ n:0, m:0, } } //状态处理方式 render(){ let {title,children}=this.props, {n,m}=this.state; return <div> 支持:<span>{m}</span> 反对: <span>{n}</span> </div> } //DOM处理方式 render(){ let {title,children}=this.props, {n,m}=this.state; return <div> 支持:<span ref={'AA'}>0</span> 反对: <span ref={'BB'}>0</span> 平局值: <span ref={'CC'}>0</span> </div> } suport=ev=>{ this.refs.AA.innerHTML++; this.computed(); } suport=ev=>{ this.refs.BB.innerHTML++; this.computed(); } computed=()=>{ let {AA,BB}=this.refs; //然后再进行操作 } supprot=ev=>{ this.refs.AA.innerHTML++; //使用箭头函数式为了保证方法中this永远是实例本身(无论在哪执行这个方法) //ev.target获取当前操作的事件源(dom元素) this.setState({ //修改状态信息并且通知render重新渲染(异步操作:如果有其他代码执行,先执行其他代码,然后再通知状态修改) n:this.state.n+1 },()=>{ //回调函数一般不用,当通知状态修改完成,并且页面重新渲染完成后,执行回调 }) } }
yarn add prop-types 基于这个插件我们可以给组件传递的属性设置规则 设置的规则不会影响页面的,但是会控制台报错显示当前文件的最新版本信
返回上一个版本
生命周期函数(钩子函数)描述一个组件或者程序从创建到销毁的过程,我们可以再过程中基于钩子函数完成一些自己的操作
生命周期
基本流程 constructor 创建一个组件 componentWillMout 第一次渲染之前 render 第一次渲染 componentDidMout 第一次渲染之后 修改流程:当组件的状态数据发生改变(setState)或者传递给组件的属性发生改变 shouldComponentUpdate 是否允许组件重新渲染(允许则执行后面函数,不允许直接结束即可) componentWillUpdate 重新熏染之前 render 第二次以后重新渲染 componentDidUpdate 重新渲染之后 属性改变: componentWillReceiveProps(nextProps/nextState):父组件把传递给组组建的属性发生改变后出发的钩子函数 接受最新属性之前,基于this.props.xxx 获取的是原有的属性信息,nextProps存储的是最新传递的属性信息 shouldComponentUpdate 是否允许组件更新, 返回true是允许,返回false 是不在继续走 componentWillUpdate: 更新之前: 和should一样,方法中通过this.state.xxx 获取的还是更新前的状态信息,方法有两个参数:nextProps/nextState存储的是最新的属性和状态 render 更新 componentDidUpdate 更新之后 卸载 componentWillUnmount :卸载组件之前(一般不用)
React是face-Book 公司开发的一款MVC版js 框架
MVC Model (数据层) View(视图层) controller(控制层)
核心思想: 通过数据的改变来影响视图的渲染(数据)
属性的属性是只读的:只能调用组件时候传递进来,不能自己在组建内部修改(但是可以设置默认值和规则)
复合组件复合组件:父组件嵌套子组件
传递信息的方式
父组件需要把信息传递给子组件