简介
- 虚拟DOM。
- JSX,jsx是JavaScript的语法扩展
- 组件,提高复用率
- 单向响应的数据流,减少重复代码。
react的脚手架安装
npm install -g create-react-app //全局安装
create-react-app 项目名 //创建项目
npm start //启动项目
目录结构
pubulic
index.html
src
App.js 根组件
App.css App组件的样式
index.js 入口文件
index.css 全局样式
package.json
组件两大类
类组件
es5方式定义组件
现在不怎么用了:
var Login = React.createClass({
userLogin:function(){
},
render:function(){
renturn(
<div>
<h1>登录</h1>
</div>
)
}
});
exprot default Login;
es6方式定义组件
improt React from 'react';
class Login extends React.Component{
userLogin(){
}
render(){
return(
<div>
<h1>登录</h1>
</div>
)
}
}
函数组件
function 函数名(){
const username = "";
function userLogin(){
}
return(
<div>
<h1>登录</h1>
</div>
)
}
export default 函数名;
JSX语法:
- 根节点只能有一个
- 注释写法: {/**/}
- js表达式要写在{}中
- 属性class换成className,for属性换为htmlFor
- 属性变为小驼峰命名
- 标签必须关闭
- css需要引入
- 变量是Number、String类型时,可以直接显示
- 变量是null、undefined、Boolean类型时,内容为空
- 对象类型不能作为子元素
- 数组会自动展开
className处理
//写法一
<div className={"nav "+(isActive ? 'active' : "")}></div>
//写法二
<div className={["nav", (isActive ? 'active' : "").jion(" ")] }></div>
style处理
//方法一
<div style={{ color: "red", fontSize: '50px' }}>hello</div>
//方法二
const style = { color: "red", fontSize: '50px' };
<div style={style}>hello</div>
条件渲染
- if条件渲染可以返回组件
- 三元运算可以选择组件
- &&运算符,第一个条件成立才执行后面的代码
{count > 0 && <h2>{count}</h2>}
渲染
如果是数组可以直接渲染出来,如果是对象无法渲染,如果数组中的元素是对象也是无法渲染的。
render(){
const list = [1,2,3];
return(
<p>{list}<p/>
)
}
//结果为123
const list = [{id:1},{id:2}]
//会报错
//正确使用map返回数组
const listDom = list.map(item=>{
return <span>{item.id}<span>
})
return(
<p>{listDom}<p/>
)
state:状态
使用state:
this.state.状态名
修改状态:
this.state.状态名 = 新的值 //可以修改但不会重新渲染
this.setState() 修改状态且会重新渲染页面
如果要以来当前state来更新下一个state的使用方法:
this.setState((preState,props)=>{
//preState:更新前的state
//props:当前props
count:preState.count+props.increment
})
this.setState的合并
props和state是异步的,出于性能考虑会把多个setState合并成一个,合并之后的state会放到状态队列,不会立即更新。所以不能依靠props和state的值来更新下一个状态。
this.state.count = 0;
hanldeCount(){
this.setState({count:this.state.count + 1})
this.setState({count:this.state.count + 1})
this.setState({count:this.state.count + 1})
}
//结果会是1
//所以应该使用上文的this.setState((preState,props)=>{})
props
组件外部传给组件的数据,通过props访问,组件内部不能修改传入的props。
类组件中this.props,函数组件中先传props然后使用直接使用props。
propsTypes规定props的类型,需要下载引入使用。
事件绑定
以下是事件绑定的几种写法
//方法一:箭头函数
userLogin(){
console.log("登录")
}
<button onClick={()=>this.userLogin()}></button>
//方法二:bind绑定this
userLogin(){
console.log(this)
}
<button onClick={userLogin.bind(this)}></button>
//方法三:在构造函数中用bind绑定this
constructor(){
super();
this.userLogin = this.userLogin.bind(this)
}
userLogin(){
console.log(this)
}
<button onClick={userLogin}></button>
样式的引入
外部引入:
import './index.css'
局部引入:首先命名必须为xxx.module.css
import styles from './buttn.module.css';
<button className = {styles.样式名称}></button>
//局部中申明全局样式需要加:
:local(.red){
color:red
}
<button className = {'red'}></button>
生命周期
● constructor:加载的时候调用一次,可以初始化 state,默认不写会自动创建;
● render:更新 dom 树;
● componentDidMount:组件渲染之后调用一次,可用于请求数据;
● shouldComponentUpdate:组件接收到新的props或者state时调用,return true就会更新dom(使用diff算法更新),return false能阻止更新(不调用render);
● componentDidUpdate:组件更新完成后调用;
● componentWillUnmount:组件卸载之后调用一次,用于清除计时器、事件绑定等;
● getDerivedStateFromError:用于错误回退 UI;
● componentDidCatch:任何一处的 javascript 报错会触发,用于错误记录;