react入门实例

01-render

从渲染一个组件开始~

使用map来渲染多个标签

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Demo extends Component{
render(){
const names = ['Alex','swift','jony']
return(
<div>
<ul>{
names.map((name,index)=>{
return(
<h1 key={index}>hello{name}</h1>
)
})
}</ul>
</div>
)
}
}

02-父子组件

父子组件的渲染

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Hello extends Component{
render(){
return <h1>hello {this.props.name}</h1>
}
}
class Demo extends Component{
render(){
const arr = [
<h1 key="1">hello</h1>,
<h2 key="2">react</h2>
]
return(
<div>
<Hello name="john"></Hello>
<ul>{
arr
}</ul>
</div>
)
}
}

03-children

类似vue中的slot,获取组件开始标签和结束标签之间的内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Hello extends Component{
render(){
return (
<ol>
{this.props.children.map((child,index)=><li key={index}>{child}</li>)
}
</ol>)
}
}
class Demo extends Component{
render(){
const arr = [
<h1 key="1">hello</h1>,
<h2 key="2">react</h2>
]
return(
<div>
<Hello>
{ arr}
</Hello>
</div>
)
}
}

获取父组件demo中的h1标签,然后渲染成li标签

04-propTypes验证参数

对传入组件的参数进行验证,安装prop-type库

1
2
3
4
5
6
7
8
9
class MyTitle extends Component{
render(){
return <h1>{this.props.title}</h1>

}
}
MyTitle.propTypes={
title:PropTypes.string
};

05-state状态控制

写一个按钮来显示state,实现每次触发onclick点击事件的时调用handleClick函数来改变state的状态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class MyClick extends Component{
constructor(props){
super(props);
this.state={success:false}
}
handleClick(){
this.setState({success:!this.state.success})
}
render(){
const text=this.state.success?'yes':'no'
return (
<button onClick={()=>{
this.handleClick()
}}>
{text}
</button>
)

}
}

官网提到使用箭头函数绑定的话,会导致父组件重复渲染,所以可以写成下面这样,绑定this值后直接调用handleClick函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class MyClick extends Component{
constructor(props){
super(props);
this.state={success:false}
this.handleClick=this.handleClick.bind(this)
}
handleClick(){
this.setState({success:!this.state.success})
}
render(){
const text=this.state.success?'yes':'no'
return (
<button onClick={
this.handleClick
}>
{text}
</button>
)

}
}

注意调用handleClick时后面是没有括号的,不然的话就会因为重复调用,然后报错

1
Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.

即,当组件在componentWillUpdate或componentDidUpdate内重复调用setState时,就会发生这种情况

个人的理解是,当调用函数添加了括号时,执行函数return的结果,这里的handleClick函数内部是没有返回结果的,所以就会重复调用,不添加括号时就只是调用函数

06-获取真实DOM

通过ref属性从组件获取真实DOM的节点

使用一个文本框,来获取用户输入的内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class MyClick extends Component{
constructor(props){
super(props);
this.value=React.createRef();
this.handleClick=this.handleClick.bind(this)
}
handleClick(){
this.value.current.focus();
}
render(){
return (
<div>
<input type="text" ref={this.value} />
<input type="button" value="click me" onClick={
this.handleClick
}></input>
</div>
)

}
}

07-双向数据绑定

手动实现一个双向数据绑定,使用onChange事件监听文本框的输入,每次输入触发handleChange事件通过setState来修改value的值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class MyBind extends Component{
constructor(props){
super(props);
this.state={value:"hi!"}
}
handleChange(event){
this.setState({value:event.target.value})
}
render(){
return (
<div>
<input type="text" value={this.state.value} onChange={this.handleChange.bind(this)}/>
<p>{this.state.value}</p>
</div>
)

}
}

08-生命周期

组件的生命周期分成三个状态,官网的图示很清晰地展示了:

  • Mounting:挂载,已插入真实 DOM
  • Updating:更新,正在被重新渲染
  • Unmounting:销毁,已移出真实 DOM

挂载

当组件实例被创建并插入 DOM 中时,其生命周期调用顺序如下:

  • constructor()
  • static getDerivedStateFromProps()
  • render()
  • componentDidMount()

更新

当组件的 props 或 state 发生变化时会触发更新。组件更新的生命周期调用顺序如下:

  • static getDerivedStateFromProps()
  • shouldComponentUpdate()
  • render()
  • getSnapshotBeforeUpdate()
  • componentDidUpdate()

卸载

当组件从 DOM 中移除时会调用如下方法:

  • componentWillUnmount()

错误处理

当渲染过程,生命周期,或子组件的构造函数中抛出错误时,会调用如下方法:

  • static getDerivedStateFromError()
  • componentDidCatch()

在组件挂载时设置定时器对透明度进行操作,实现文本透明度渐变的效果

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
class MyBind extends Component{
constructor(props){
super(props);
this.state={
opacity:1.0
}
}
componentDidMount(){
this.timer=setInterval(function(){
var opacity=this.state.opacity;
opacity-=.05;
if(opacity<0.1){
opacity=1
}
this.setState({
opacity:opacity
})
}.bind(this),100
)
}
render(){
return (
<div style={{opacity:this.state.opacity}}>
hello {this.props.name}
</div>
)

}
}

09-Ajax请求

使用componentDidMount方法设置Ajax请求,等请求成功响应再渲染页面。

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
class MyBind extends Component{
constructor(props){
super(props);
this.state={
username: '',
lastGistUrl: ''
}
}
componentDidMount(){
$.get(this.props.source, function(result) {
var lastGist = result[0];
this.setState({
username: lastGist.owner.login,
lastGistUrl: lastGist.html_url
});
}.bind(this));
}
render(){
return (
<div>
{this.state.username}'s last gist is <a href={this.state.lastGistUrl}>here</a>.
</div>
)
}
}

阮一峰老师用的是GitHub的api,好像已经挂了。。。。

10、创建项目

1
2
3
4
5
6
7
npm install create-react-app -g
create-react-app React-Mock-Demo
cd React-Mock-Demo
npm install

npx create-react-app react-mock-demo//注意不要又-又驼峰
cd react-mock-demo

不得不说npm装得真慢

11、暴露config

1
npm run eject

creat-react-app后,将配置文件暴露出来

参考文章:

查看评论