react
一.虚拟dom dom : 浏览器中,提供的概念,用js对象,表示页面上的元素,并提供了操作元素的api
虚拟dom: 是框架中的概念; 它是开发框架的程序员,手动用js对象来模拟dom元素和嵌套关系;
- 本质: 用js对象,来模拟dom元素和嵌套关系
- 目的: 就是为了实现页面元素的高效更新
- tree diff : 新旧两棵dom树,逐层对比的过程,就是tree diff; 当整颗dom逐层对比完毕,则所有需要被按需更新的元素,必然能够找到
- component diff : 在进行tree diff 的时候,每一层中,组件级别的对比,叫做 component diff
- 若对比前后,组件的类型相同 ,则暂时认为此组件不需要被更新
- 若对比前后,组件的类型不相同,则移除旧组件,创建新组件,并追加到页面上
- element diff : 在进行组件对比的时候,如果两个组件类型相同 ,则需要进行元素级别的对比
yarn add react-create-app -g
2.创建一个项目
react-create-app [项目名称project name]
3.启动react服务
yarn start
。yarn start 启动服务
yarn bulid 打包文件
yarn test 测试
yarn eject 显示相关的配置文件
react是基于webpack创建项目,react-create-app命令已帮我们配置好了相关配置,我们只需要操作react即可
四.jsx 在react中为了减少dom操作,使用js+xml形式书写代码
但这里的xml标签比真正的xml要严格多,标签必须要有闭合
// 1.导入包
import React from 'react';
import ReactDOM from 'react-dom';
// 2.创建虚拟dom
// var div2 = React.createElement('p',null,'这是一个p标签')
// var div1 = React.createElement('div',null,'这是根标签',div2)// 以上写法太麻烦,所以react提供了jsx语法 ,
// jsx语法通过bobal转成上面createelement样式,再渲染给页面
let str = '这是一段内容';
let text = '这是一段文件'
let val = true;
let und = undefined;
let arr = ['这是第一个h1','这是第二个h1']
let content =
{str}{text}{val ? true.toString() : false.toString()}{und}{null}
{arr.map((item,index)=>{
return {item}
})}
// 3.把创建的虚拟dom放到页面上
// ReactDOM.render(div1,window.root)
ReactDOM.render(content,window.root)
五.组件 函数式组件写法
这是Hollow.jsx页面中的中代码
import React from 'react';
// export default 向外暴露一个组件
export default function Hollow(props) {
return
{props.data.name}
{props.data.age}
{props.data.title}
}
把写好的组件导入到下面这个index.js页面,然后由下面的页面渲染到页面上
// 创建组件 虚拟dom元素, 生命周期
import React from 'react';
// 把创建好的组件 和 虚拟dom 放到页面上展示
import ReactDOM from 'react-dom';
// 这里导入的jsx文件必须写后缀名,不然报错.除非有相关的配置,可以不写
import Hollow from '../component/1.hollow.jsx'let obj = {
name: '的口吻',
age: '25',
title: '这是一个对象'
}ReactDOM.render(, window.root)
继承性组件写法class
首先了解一下类继承
1.在 class 的 { } 区间内,只能写 构造器、静态方法和静态属性、实例方法
2.class 关键字内部,还是用 原来的配方实现的;所以说,我们把 class 关键字,称作 语法糖;
3.class 中都有一个构造器,如果我们程序员没有手动指定构造器,那么,可以认为类内部有个隐形的、看不见的 空构造器,类似于 constructor(){}
4.构造器的作用,就是,每当 new 这个类的时候,必然会优先执行 构造器中的代码
class Person{
constructor(name,age){
// constructor放的是实例共有的私有属性
this.name = name;
this.age = age;
}
// 在这里面直接写的方法是实例的共有的方法
say(){
console.log('这是一个实例公有的方法')
}
// static 静态属性 放的是person这个类私有的属性与方法
static a = 10;
static Hi(){
console.log('这是这个类私有的方法,外界不可调用 ')
}
}// extends继承
class A extends Person{
constructor(name,age){
// super 是一个函数,而且,它是 父类的 构造器;子类中的 super,其实就是父类中,constructor 构造器的一个引用;
// 构造器继承父亲的方法与属性,首先调用super方法,才有this
// super必须写在this之前
super(name,age);
// 不写super会报错
console.log(this.name,this.age)
}
}// new 一个实例对象
var a1 = new Person('的口吻',25)
a1.say()var a2 = new A('大中企业',254)
a2.say()
class类组件的写法
// 创建组件 虚拟dom元素, 生命周期
import React,{Component} from 'react';
// 把创建好的组件 和 虚拟dom 放到页面上展示
import ReactDOM from 'react-dom';
class Hollow extends React.Component{
constructor(props){
super(props);
// props只可读
this.state={// state可读可写,相当vue中的data
name:'李四',
age:this.props.data.age
}
}
// render 函数的作用,是 渲染 当前组件所对应的 虚拟DOM元素
render(){
return
{this.props.data.name}
{this.state.name}
{this.state.age}
}
}var lis = {
name:'张三',
age:30,
sex:'men'
}ReactDOM.render(,window.root)
通过构造函数创建的组件是无状态组件,只有props,只可读,不可写
通过class创建的组件是有状态组件,有props , state 可读,可写
一般情况下,不需要通过外界传递数据过来,使用无状态组件
需要通过ajax传递数据用有状态组件,可以读写
六. 父子组件传值,事件 【react|react 简单入门】点击子组件的按钮改变父组件的字体背景颜色
// 1.导入包
import React from 'react';
// 创建组件 虚拟dom元素, 生命周期
import ReactDOM from 'react-dom';
// 把创建好的组件 和 虚拟dom 放到页面上展示
import "bootstrap/dist/css/bootstrap.css"// 2.创建虚拟dom父组件
class Panel extends React.Component {
constructor() {
super();
this.state = {color:'success'}
}
change=(color)=>{
this.setState({color:color})
}
render() {
return
}
}
// 子组件
class Header extends React.Component {
constructor() {
super();
}
chage=()=>{
this.props.chan("warning")
}
render() {
return
{this.props.data}
// method1
{/* */}
// method2
{}
}
}
// 3.把dom渲染到页面上
ReactDOM.render(, window.root)
校验属性
import React from 'react';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';
class Title extends React.Component{
constructor(){
super()
}
// 要求num必须是一个数字类型的;
// 抛出一个警告,但页面会渲染;
static PropTypes={
n:PropTypes.number
}// 默认属性;
//如果属性被传行间属性传递进来,那么会默认获取当前的属性;如果行间传递,那么会走行间属性;
static defaultProps = {
n:"10"
}
render(){
return {this.props.n}
}
}
ReactDOM.render( ,document.getElementById('root'))
受控组件
受控组件可模仿vue的双向数据绑定
受控组件一般是一些form表单元素,
受控组件的值不可更改
必须添加onchange事件
class Box extends React.Component{
constructor(){
super();
this.state={
str:"请输入用户名",
str1:"请输入内容"
}
}
change=(key,e)=>{//事件
console.log(e,e.target)
this.setState({[key]:e.target.value})
}
render(){
return
this.change("str",e)}/>
this.change("str1",e)}/>
}
}
非受控组件
class Sum extends React.Component {
constructor() {
super();
this.state = { total: 0 }
}
change = () => {console.log(this.refs)
// var total = Number(this.refs.a.value)+Number(this.refs.b.value)
var total = Number(this.refs.a.value) + Number(this.b.value)
this.setState({ total })}
render() {
return
+
{/*x代表的真实的dom,把元素挂载在了当前实例上*/}
{ this.b = x }} />=
{this.state.total}
}
}
react 生命周期
- 生命周期的概念:每个组件的实例,从 创建、到运行、直到销毁,在这个过程中,会出发一些列 事件,这些事件就叫做组件的生命周期函数;
- React组件生命周期分为三部分:
- 组件创建阶段:特点:一辈子只执行一次
componentWillMount:
render:
componentDidMount:
- 组件运行阶段:按需,根据 props 属性 或 state 状态的改变,有选择性的 执行 0 到多次
componentWillReceiveProps: 接收
shouldComponentUpdate:
componentWillUpdate:
render:
componentDidUpdate:
- 组件销毁阶段:一辈子只执行一次
componentWillUnmount:
推荐阅读
- 前端|面试官(谈谈Vue和React的区别())
- react|高德地图的使用及自定义图标
- React|【React Native开发】React Native控件之RefreshControl组件详解(21)
- React|React Native开源项目-嘎嘎商城客户端(持续更新中)
- 工作与生活|2016总结,真正新的里程碑和新起点
- React|【React Native开发】React Native应用设备运行(Running)以及调试(Debugging)(3)
- React|【React Native开发】React Native控件之ListView组件讲解以及最齐全实例(19)
- React|React Native控件之PullToRefreshViewAndroid下拉刷新组件讲解(20)
- React|【React Native开发】React Native控件之Text组件讲解(9)
- react学习之旅|react+antd-mobile之项目构建+基础配置