react教程


版本

当前版本为React Fiber版本,也就是React16这个版本(2019年)

准备工作
1
2
3
4
5
6
7
vscode插件: Simple React Snippets
chrome插件:React developer tools:点击设置图标,选中highlight Updates,这个高亮显示说明组件已更新
# npm install -g create-react-app
# mkdir reactDemo && cd reactDemo
# create-react-app . // 脚手架会安装好npm包
// # yarn install
# npm start
npm包
1
2
axios
react-transition-group: react第三方动画组件
根目录文件
1
2
3
package-lock.json:这个文件用一句话来解释,就是锁定安装时的版本号,并且需要上传到git,以保证其他人再npm install 时大家的依赖能保证一致。
mainifest.json:移动端配置文件
serviceWorker.js: 这个是用于写移动端开发的,PWA必须用到这个文件,有了这个文件,就相当于有了离线浏览的功能。
入口文件src/index.js
1
2
3
4
import React from 'react'
import ReactDOM from 'react-dom'
import App from './App' // 一定要大写,JSX规定自定义组件必须要大写
ReactDOM.render(<App />,document.getElementById('root'))
React注意事项
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// this.state.inputValue = e.target.value 不支持,因为React中改变值需要使用this.setState方法
this.setState({ // 这方法是异步的,所以有时候要写回调函数
inputValue: e.target.value
}, () => {
console.log(111)
})

// 重复渲染问题:因为修改了props属性或者state状态都会重新渲染组件,通过shouldComponentUpdate进行阻止
shouldComponentUpdate (nextProps, nextState) {
if (nextProps.content1 !== this.props.content1) {
return true
} else {
return false
}
}
JSX的注意事项
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 和vue一样,组件都需要一个根标签,但是真不想展示根标签,可以使用Fragment标签
import React,{Component,Fragment } from 'react'
render(){
return (
<Fragment>
<div><input /> <button> 增加服务 </button></div>
<ul>
<li>头部按摩</li>
</ul>
</Fragment>
)
}

{/* 我是注释内容 */} // 注释:因为JSX中的{}里就是js内容

<input className="input" /> // 将class换成className,防止和js中的class类名 冲突

<div dangerouslySetInnerHTML={{__html: htmlContent}}></div> // htmlContent是表示绑定在react中的数据,渲染成html,而不仅仅是展示内容

<label htmlFor="jspang">加入服务:</label> // label的for换成htmlFor,也是为了防止和js中的for冲突
<input id="jspang" />
基本组件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import React, {Component} from 'react'
class Xiaojiejie extends Component{
constructor (props) {
super(props)
this.state = { inputValue: '基本服务', list: ['基础按摩', '精油'] }
}
render(){
return (
<Fragment>
<div>
<input value={this.state.inputValue} onChange={this.inputChange.bind(this)} />
{/* vue:<input :value="inputValue" @change="inputChange" /> */}

<button onClick={this.addList.bind(this)}> 增加服务 </button>
</div>
<ul>
{
this.state.list.map((item,index)=>{
return <li key={index} onClick={this.deleteItem.bind(this, index)}>{item}</li>
})
}
</ul>
</Fragment>
)
}
inputChange (e) {
// this.state.inputValue = e.target.value 不支持,因为React中改变值需要使用this.setState方法
this.setState({
inputValue: e.target.value
})
}
addList(){
this.setState({ // 注意:这个方法是异步的
list:[...this.state.list,this.state.inputValue]
})
}
deleteItem(index){
let list = this.state.list
list.splice(index,1)
this.setState({
list:list
})
}
}
export default Xiaojiejie
如何快速获取元素
1
2
3
4
5
6
7
8
<input
type="text"
className="input"
ref={(input) => {
console.log(input) // <input type="text" class="input" />
this.input = input // 将DOM元素赋值给this.input
}}
/>
哪个钩子请求接口

componentDidMount生命周期函数里请求ajax

react动画
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import React, { Component } from 'react'
class Boss extends Component {
constructor (props) {
super(props)
this.state = { isShow: true }
}
render () {
return (
<div>
<div className={this.state.isShow ? 'show' : 'hide'}>BOSS级人物-孙悟空</div>
<div><button onClick={this.toToggle.bind(this)}>召唤Boss</button></div>
</div>
)
}
toToggole(){
this.setState({
isShow:this.state.isShow ? false : true
})
}
}

// css
.show{ opacity: 1; transition:all 1.5s ease-in;}
.hide{opacity: 0; transition:all 1.5s ease-in;}
第三方动画:react-transition-group
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// css样式书写和vue差不多
import { CSSTransition } from 'react-transition-group'
render() {
return (
<div>
<CSSTransition
in={this.state.isShow} //用于判断是否出现的状态
timeout={2000} //动画持续时间
classNames="boss-text" //className值,防止重复
unmountOnExit // 元素退出自动删除DOM
>
<div>BOSS级人物-孙悟空</div>
</CSSTransition>
<div><button onClick={this.toToggole}>召唤Boss</button></div>
</div>
);
}
.boss-text-enter{ opacity: 0; }
.boss-text-enter-active{ opacity: 1; transition: opacity 2000ms; }
.boss-text-enter-done{ opacity: 1; }
.boss-text-exit{ opacity: 1; }
.boss-text-exit-active{ opacity: 0; transition: opacity 2000ms; }
.boss-text-exit-done{ opacity: 0; }
react-transition-group控制多个元素
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import {CSSTransition , TransitionGroup} from 'react-transition-group'
<TransitionGroup>
{
this.state.list.map((item,index)=>{
return (
<CSSTransition
timeout={1000}
classNames='boss-text'
unmountOnExit
appear={true}
key={index+item}
>
<XiaojiejieItem
content={item}
index={index}
deleteItem={this.deleteItem.bind(this)}
/>
</CSSTransition>
)
})
}
</TransitionGroup>
参考教程

技术胖教程