REACT:用于构建用户界面的js库
环境
- node
- 官方脚手架:create-react-app
- 全局安装
npm i -g create-react-app yarn add create-react-app -g- 查看版本
create-react-app --version
创建项目
create-react-app my-app
vscode插件
ES7 React/Redux/GraphQL/React-Native snippets
项目目录
README.md 项⽬说明⽂档
node_modules 依赖⽂件夹
package.json npm依赖
.gitignore
public 静态资源
favicon.ico
index.html
manifest.json
src 源码
App.css
App.js
App.test.js 测试
index.css
index.js ⼊⼝js
logo.svg
serviceWorker.js 对PWA的⽀持
react和react-dom两个库深⼊理解
- React的api是很少的,核⼼就是js功⼒
- React设计之初就是使⽤JSX来描述UI,所以解耦了和DOM的操作
- react只做逻辑层
- react-dom做渲染层,去渲染实际的DOM
- 备注:换到移动端,可以⽤别的渲染库
深度剖析JSX的实质
- JSX语法即JS和html的混合体,实际的核⼼逻辑就是⽤js去实现的
- JSX的实质就是React.createElement的调⽤
state
初始化状态
// constructor(props) {
// super(props);
// this.state = {
// count: 0,
// };
// }
state = {
count: 0,
};
更新
this.setState({
count: this.state.count + 1,
});
注意:setState是异步的,第二个参数可选,传入一个回调函数可以获取到最新的state
...
// 方法一
this.setState(
{
count: this.state.count + 1,
},
() => {
console.log(this.state.count); // 1
}
);
console.log(this.state.count); // 0
// 方法二
this.setState(
(prevState, prevProps) => {
console.log(this.state.count, prevState.count); // 0 1
return {
count: prevState.count + 1,
};
},
() => {
console.log(this.state.count); // 2
}
);
console.log(this.state.count); // 0
// 简写
// this.setState((prevState, prevProps) => ({
// count: prevState.count + 1,
// }));
}
...
props
⽗组件向⼦组件传递属性利⽤props接收 例:
- 父组件
<PropsDemo name='steven' /> - 子组件
import React from 'react'; // class组件 export default class PropsDemo extends React.Component { render() { return <div>My name is {this.props.name}.</div>; } // 函数组件 // export default function PropsDemo(props) { // return <div>My name is {this.props.name}.</div>; // }
条件渲染与数据循环
条件渲染
- 三目表达式(一般使用)
this.state.showTitle ? <h1>{this.props.title}</h1> : null; - if else写法
数据循环渲染
例:
...
<ul>
{this.state.goods.map((value) => (
<li key={value.title}>
{value.title}:{value.price}元
</li>
))}
</ul>
...
事件监听的实现
以点击事件为例⼦,⼩驼峰写法,事件名⽤{}包裹
<button onClick={}></button>
由于react的this指向问题,注意事件绑定
- 利用bind绑定
constructor(props) {
...
this.hideTitle = this.hideTitle.bind(this);
}
hideTitle() {...};
<button onClick={this.hideTitle}>隐藏标题</button>
- 箭头函数写法
showTitle = () => {...};
<button onClick={this.hideTitle}>隐藏标题</button>
- 直接用箭头函数返回一个函数
hideTitle() {...};
<button onClick={() => this.hideTitle()}>隐藏标题</button>
React样式编写
行内样式写法
<p style={{ fontSize: '100px', color: '#f00' }}>样式</p>
添加类名
<p className='title'>样式</p>
添加属性
<img src={logo} />
生命周期
import React, { Component } from 'react';
class LifeCycleSon extends Component {
constructor(props) {
super(props);
console.log('1.构造函数');
}
componentWillMount() {
console.log('2.组件将要挂载');
}
componentDidMount() {
console.log('4.组件已经挂载');
}
componentWillReceiveProps() {
console.log('5.⽗组件传递的属性有变化,做相应响应');
}
shouldComponentUpdate() {
console.log('6.组件是否需要更新,返回布尔值,优化点');
return true;
}
componentWillUpdate() {
console.log('7.组件将要更新');
}
componentDidUpdate() {
console.log('8.组件已经更新');
}
componentWillUnmount() {
console.log('9.组件已经销毁');
}
render() {
console.log('3.组件渲染');
return <div>组件生命周期</div>;
}
}
export default class LifeCycle extends Component {
constructor(props) {
super(props);
this.state = {
show: true,
title: '标题',
};
const timer1 = setTimeout(() => {
this.setState({
title: '新标题',
});
clearTimeout(timer1);
}, 1000);
const timer2 = setTimeout(() => {
this.setState({
show: false,
});
clearTimeout(timer2);
}, 2000);
}
render() {
return (
<div>
<p>生命周期</p>
{this.state.show ? (
<LifeCycleSon title={this.state.title} />
) : (
'组件已经销毁'
)}
</div>
);
}
}
React实现双向数据绑定
要点
- 动态绑定value属性
- 监听input的onChange事件
constructor(props) {
super(props);
this.state = {
value: '双向数据绑定',
};
}
change(e) {
this.setState({
value: e.target.value,
});
}
<h1>{this.state.value}</h1>
<input value={this.state.value} onChange={(e) => this.change(e)} />