1. 搭建环境
安装react脚手架 >npm install create-react-app -g
创建文件 >create-react-app 项目名称
启动项目 >npm start
删除不必要文件——src文件夹里面删除,新建index.js入口文件
2. JSX的理解
JSX的基本语法规则:遇到HTML标签(以<开头),就用HTML规则解析;遇到代码块(以{开头),就用JavaScript规则解析。
JSX本质:写结构的语法糖,会被babel工具转成js,这个js代码运行之后会得到一个对象,这个对象是虚拟DOM(virtual DOM),并且有有type,children,描述了DOM结构。
相对于普通对象,这个这个js是虚拟的,并且描述了DOM结构。
JSX的作用:结构清晰,看着就是HTML的结果。ReactDOM将jsx语法转成JavaScript。
有JSX的地方就有引入React。
//JSX ReactDOM.render( <div> <p>内容一</p> </div>, document.getElementById('root') ); //经过babel转义之后的JavaScript ReactDOM.render( React.createElement( "div", null, React.createElement( "p", null, "\u5185\u5BB9\u4E00" ) ), document.getElementById('root') );
关注点:
1. JSX表达式
2. JSX嵌套
3. JSX样式
4. JSX属性
5. JSX闭合标签
{}能够渲染的元素:
Node:包括element。比如数字、布尔值、字符串、jsx标签、array。对象不能渲染。注意array有对象元素是不能渲染的。
element:react element
注意点:
用()抱起来一个整体
必须有只有一个父级,如果需要几个标签并行,可以引入{Fragment} from react,虚拟标签,不会被解析。
import React,{Fragment} from 'react'; import ReactDOM from 'react-dom'; let a = 1; let b = 2; let jsx1 = ( <h1>标题</h1> ); ReactDOM.render( <Fragment> <p>{a + b}</p> <p>{`${a} ${b}`}</p> {jsx1} <p/> <p style={{color:'red',marginLeft:'50'}}></p> <p className='abc'></p> </Fragment>, document.getElementById('root') );
3. 组件
表现形式:函数式组件,类式组件
注意:组件首字母必须大写,如果是小写开头,不解析,直接打印在浏览器的elements中。
//函数式组件,必须有return function Parent(){ return ( <div>Parent</div> ) } //类式组件,必须有render方法,且有return class Child extends Component { render(){ return ( <div>Child</div> ) } }
3.1 props
组件的数据传递:
函数式组件是通过参数接收;
类式组件时通过实例的属性接收;在constructor里面是通过参数接收,并且如果不super接收props,打印的this.props是undefined;
默认数据props:给类加defaultProp属性,值是对象
props数据类型验证:引入prop-type。 import PT from 'prop-types';
string
bool
number
array
object
func
symbol
import React from 'react'; import PT from 'prop-types'; //函数式组件必须有返回值,返回jsx //props通过参数接收 export default function People(props){ return ( <div> People {props.name} {props.abc()} </div> ) } //props默认值 People.defaultProps = { name:'--', abc:f=>f } //props参数数据类型验证 People.prototype = { name:PT.string, abc:PT.func }
import React,{Component} from 'react'; import People from './People'; //类式函数必须有render函数,并且函数返回值是JSX //props通过实例的属性接收 export default class Man extends Component { constructor(props){ super(); console.log(1,this.props);//props是空的,因为还没有挂载,需要在super里面加参数props } render(){ let {name} = this.props; console.log(this.props) return ( <div>Man {name} <People>Man-people</People> </div> ) } }
3.2 state
什么是state:
state是组件内部状态,视图。如果需要内容是可以修改的,就需要用到state。
React更新视图的原理:
就是改变state,从一个状态变成另一个状态。
state的设置和获取:
只有类式组件才有state,函数式组件没有state。
state的修改的过程的理解:
实例设置setState(this.setState是通过component继承的),合并setState;
state修改;
render方法执行,生产新的虚拟DOM;
新的虚拟DOM和旧的虚拟DOM比对,找出修改的地方,将页面中变化的地方修改。
state的特性:
state是内容部状态—— 一个组件不同的实例,其中一个实例修改,只改变当前的实例,其他实例不修改
setState合并更新—— 同一个事件循环调用多次setState,会先合并setState,在去修改state
setState异步更新***—— 同修改setState之后打印state,还是之前的state,不是更新之后的state
state更新之后马上获取state的方法
//因为setState是异步的,下面方法获取更新后的值 //方法一,存储变量 let changeNum = Math.random(); this.setState({ number : changeNum }) console.log(changeNum); //方法二,setState内部用回调函数 this.setState({ number : Math.random() }) this.setState((prevState,props)=>{ console.log(prevState,props) //修改之后的number return { name : 'mike' } })
4. 事件
语法:onClick={((event)=>{})}
事件对象的理解
事件对象是经过包装过的合成事件对象。
事件对象下面的属性
nativeEvent —— 浏览器原生的事件对象
preventDefaule —— 阻止默认事件
stopPropagetion —— 阻止冒泡
Target —— 事件的发生地方
currentTarge —— 当前元素
this的理解——将this指向实例的方法:
1.行内 箭头函数 绑定this
箭头函数,this是有上下文决定的
形式:
onClick={()=>{
}}
2.行内 函数bind 绑定this
存在问题:每次点击,bind绑定this,都生产新的函数,即使state不更新,视图也会更新,影响性能。
形式:
onClick={(function(){
}).bind(this)}
改造:
事件名(){}
onClick={this.事件名.bind(this)}
3.constructe中 对事件回调函数绑定this
constructe中:this.事件名 = this.事件名.bind(this)
事件名(){}
onClick={this.事件名}
4.类属性*******
形式:
事件名=()=>{this}
发的发到付