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}