0%

React入门1

创建项目执行的命令

  • npm install -g create-react-app
  • create-react-app [项目名称]
  • cd进项目文件
  • 再执行npm start就可以启动react项目

jsx语法

  • jsx语法就是js+xml的语法
1
2
3
4
5
6
//render是一个渲染函数
//第一个参数含义是要插入的元素
//第二个参数含义是插入的位置,在这里的位置是指public的index.html文件中id为root的元素
ReactDOM.render(<h1>Hello React</h1>,
document.getElementById('root')
);
  • 解读jsx语法:遇到<>按照html语法解析,遇到{}按照js语法解析,例如下面代码和上面的代码有一样的效果
1
2
3
4
const react = "React"
ReactDOM.render(<h1>Hello {react}</h1>,
document.getElementById('root')
);

React元素渲染

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//在这段代码中定义了一个tick函数,然后使用setInterval设置每隔1秒调用tick函数
//tick调用则重新渲染了页面,这是react实时渲染的功能
function tick() {
//在定义html标签变量时,需要用()括起来
const element = (
<div>
<h1>Hello World!</h1>
<h2>It is {new Date().toLocaleTimeString()}.</h2>
</div>
)
ReactDOM.render(element,
document.getElementById('root')
);
}
setInterval(tick, 1000);

React的组件

  • 创建一个jsx文件,使用ES6的语法来创建一个类,使用类的形式来表示一个组件
1
2
3
4
5
6
7
8
9
10
11
12
import React from "react"

//使用类的形式创建组件,Hook形式
//组件类需要继承React.Component
class App extends React.Component{
//渲染函数
render(){
return <h1>Hello React Component!</h1>
}
}
//将App类暴露出去,让其他类可识别
export default App
  • 再index.js中引入组件
1
2
3
4
5
6
import React from 'react';
import ReactDOM from 'react-dom';
import App from "./app"

//引入后使用标签为App的元素即可调用App类中的渲染函数
ReactDOM.render(<App />, document.getElementById('root'))
  • React项目都是由很多个组件组成的,所以组件在React中是很重要的。

porps属性

  • 当 React 元素为用户自定义组件时,它会将 JSX 所接收的属性(attributes)以及子组件(children)转换为单个对象传递给组件,这个对象被称之为 “props”。
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 from "react"
import Home from "./home"
import MyNav from "./MyNav"

//使用类的形式创建组件,Hook形式
class App extends React.Component{
//渲染函数
render(){
const nav1 = ["C", "C++", "C#"]
const nav2 = ["Python", "Go", "Java"]
return(
<div>
<h1>Hello React Component!</h1>
<Home/>
{/* 在这里的MyNav元素为自定义组件,所以这里的nav和title
属性转换为props对象传递给MyNav组件,MyNav组件再把属性值
渲染到它的组件上,再把props传回到App组件中*/}
<MyNav nav={nav1} title="语言1"/>
<MyNav nav={nav2} title="语言2"/>
</div>
)
}
}
export default App
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
import React from "react"

//该组件接收唯一带有数据的props对象并返回一个React元素,这使一个类组件
//props在MyNav类中是只读的,不能修改
//然后使用jsx语法来渲染
export default class MyNav extends React.Component{
render(){
return(
<div>
<h3>{this.props.title}</h3>
<ul>
{
this.props.nav.map((element, index)=>{
return <li key={index}>{element}</li>
})
}
</ul>
</div>
)
}
}
//函数组件,效果和上面的类组件一样
/*function MyNav(props) {
return (
<div>
<h3>{this.props.title}</h3>
<ul>
{
this.props.nav.map((element, index)=>{
return <li key={index}>{element}</li>
})
}
</ul>
</div>
)
}*/

组件的状态State

  • State 与 props 类似,但是 state 是私有的,并且完全受控于当前组件
  • 当要设置State时,应调用setState方法进行设置
  • 一般可以使用state来设置自定义组件的属性值,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import React from "react"
export default class Clock extends React.Component{
constructor(props){
super(props);
this.state = {
date: new Date()
};
}
render(){

return (
<div>
<h1>It is {this.state.date.toLocaleTimeString()}.</h1>
</div>
)
}
}

React生命周期函数

  • componentWillMount:在组件渲染之前执行
  • componentDidMount:在组件渲染之后执行
  • shouldComponentUpdate:返回true和false,true代表运行改变,false代表不允许
  • componentWillUpdate:数据在改变之前执行()
  • componentDidUpdate:数据修改完成执行
  • componentWillReveiceProps:Props发生改变执行
  • componentWillUnmount:组件卸载前执行

  • 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
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import React from "react"
import Home from "./home"
import MyNav from "./MyNav"
import StateComponent from "./StateComponent"
import Clock from "./clock"
import ComponentLife from "./ComponentLife"

//使用类的形式创建组件,Hook形式
class App extends React.Component{
constructor(props){
super(props)
this.state = {
title:"文本1"
}
}
// changeHandler = ()=>{
// this.setState(
// {title:"文本2"}
// )
// }
changeHandler1 = (text)=>{
this.setState(
{title:text}
)
}
//渲染函数
render(){
const nav1 = ["C", "C++", "C#"]
const nav2 = ["Python", "Go", "Java"]
return(
<div>
{/*
<h1>Hello React Component!</h1>
<Home/>
<MyNav nav={nav1} title="语言1"/>
<MyNav nav={nav2} title="语言2"/>
<StateComponent/>
<Clock />
*/}
<ComponentLife title={this.state.title} changeHandler2={this.changeHandler1}/>
</div>
)
}
}
export default App
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
46
47
48
49
import React from "react"
export default class ComponentLife extends React.Component{
constructor(props){
super(props)
this.state = {
count:10
}
}
componentWillMount(){
console.log("componentWillMount")
}
componentDidMount(){
console.log("componentDidMount")
}
shouldComponentUpdate(){
console.log("shouldComponentUpdate")
return true;
}
componentWillUpdate(){
console.log("componentWillUpdate")
}
componentDidUpdate(){
console.log("componentDidUpdate")
}
componentWillReceiveProps(){
console.log("componentWillReceiveProps")
}
componentWillUnmount(){
console.log("componentWillUnmount")
}
changeHandler = ()=>{
this.setState({
count:this.state.count+=1
})
}
changeHandler1 = ()=>{
this.props.changeHandler2('text2')
}
render(){
const { count } = this.state
return(
<div>
LifeTime:{count} - {this.props.title}
<button onClick={this.changeHandler}>增加</button>
<button onClick={this.changeHandler1}>修改title</button>
</div>
)
}
}

setState更新是同步还是异步

  • 如果执行下面的代码,setState方法是同步的,当setState还没执行完时,console.log方法会被调用,所以会出现数据不一致的现象
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
import React from "react"

export default class SetStateDemo extends React.Component{
constructor(){
super();
this.state = {
count:0
}
}
increment = ()=>{
this.setState(
{count:this.state.count+1}
)
console.log(this.state.count)
}
render(){
return (
<div>
setState是同步还是异步
<p>{this.state.count}</p>
<button onClick={this.increment}>修改</button>
</div>
)
}
}
  • 处理这个问题有两种办法,第一种是使用React给定的解决方法
1
2
3
4
5
6
7
8
//把increment函数改成下面函数
//第二个参数lambda里的代码会等第一个参数执行完再执行
increment = ()=>{
this.setState(
{count:this.state.count+1},()=>{
console.log(this.state.count)
})
}
  • 第二种是使用ES6的异步关键字(async/await)来解决
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
async increment(){
await this.setStateAsync(
{count:this.state.count+1})
console.log(this.state.count);
}
setStateAsync(state){
return new Promise((resolve)=>{
this.setState(state, resolve)
})
}
render(){
return (
<div>
setState是同步还是异步
<p>{this.state.count}</p>
<button onClick={this.increment.bind(this)}>修改</button>
</div>
)
}
-------------本文结束感谢您的阅读-------------