react之初体验

1.关于react的class声明、初始化及输出的方法(包含生命周期及更新过程)
推荐款:

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
50
51
52
53
54
55
56
57
58
class Index extends Component{
constructor(props){
super(props);
this.state = {
foo : "bar"
};
};
componentWillMount(){
<!-- 会在render之前被调用,但是这个时候没有任何渲染出来的结果
即使调用this.setState修改状态也不会引发重新绘制
所有可以在这个函数里做的事情,都可以提前到constructor中间去做 -->
};
componentWillReceiveProps(nextProps){
<!--只要父组件的render函数被调用,在render函数里被渲染的子组件也会经历更新过程
不管父组件传给子组件的props改变没有都会触发子组件的componentWillReceiveProps
注意:this.setState方法触发更新过程不调用此函数,因为此函数
适合根据函数内部的新props值,也就是接受的参数来计算是不是要更新内部状态
this.props表示上一次渲染时的props值,nextProps表示这一次传进来的props值
进行对比,有变化时才调用this.setState方法更新内部状态 -->
};
shouldComponentUpdate(nextProps,nextState){
return(nextProps.x !== this.props.x) || (nextState.y !== this.state.y);
<!-- 此函数是除了render函数外在生命周期中最重要的函数
render决定该怎么渲染,此函数决定一个组件什么时候不需要渲染,render和此函数
也是react声明周期中唯二要求有返回值的函数
render函数返回值用于构造DOM对象,此函数返回一个布尔值,告诉react库
这个组件在这此次更新中是否要继续,并且先调用此函数在调用render -->
};
componentWillUpdate(){
<!-- 类似componentWillMount -->
};
render(){
return();
};
componentDidMount(){
<!-- render函数被调用完了之后,此函数不会被立刻调用
此函数调用的时候,render函数返回的东西已经引发渲染,
组件已经被“装载”到DOM树上了,且此函数只在客户端调用-->
};
componentDidUpdate(){
<!-- 此函数与componentDidMount不同处在于此函数不论在服务器端
还是客户端都会被调用,但正常情况下不在服务器端调用,如果
在服务器端被调用了,说明程序有错误 -->
};
componentWillUnmount(){
<!-- 卸载过程只涉及这一个函数,此函数的工作往往和componentDidMount
有关,如果在componentDidMount函数在用非react方法创造了一些DOM元素,
如果不清理掉可能造成内存外泄,所以会用到此函数清理这些DOM元素 -->
}
};

Index.defaultProps = {
return {
indexProps : 0
}
};

export default Index;

补充关于声明周期:
如果同时渲染了三个组件,整个过程如下(来自console.log())

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
enter constructor First
enter componentWillMount First
enter render First

enter constructor Second
enter componentWillMount Second
enter render Second

enter constructor Third
enter componentWillMount Third
enter render Third

enter componentDidMount First
enter componentDidMount Second
enter componentDidMount Third

关于更新过程:

逐渐淘汰款:

1
2
3
4
5
6
7
8
9
10
11
12
13
const Index = React.createClass({
getInitialState : function(){
return { foo : "bar" };
},
getDefaultProps : function(){
return { indexProps : 0 };
},
render(){
return();
}
});

export default Index;

2.数据的双向绑定
通过props从父组件传递数据给子组件很容,但是组件之间的交流是相互的,于是如何从子组件传递数据给父组件也显得很关键。

父组件定义一个函数,通过props传递到子组件,子组件在执行事件时通过props调用父组件的函数,向函数传入参数,父组件的函数收到参数后进行对应的修改。

3.关于refs

refs是访问到组件内部DOM节点唯一可靠的方式,并且refs会自动销毁对子组件的引用。要调用refs必须在render之后才可以,因为render之后才能创在处DOM对象,而refs则是去访问该对象节点。

5月16日 今日份的react问题

1.在使用react-responsive插件的时候做响应式但是在浏览器刷新出来是一片空白的。
最开始的写法如下:

1
2
3
4
5
6
<MediaQuery query="(min-device-width: 1224px)">
<PCIndex />
</MediaQuery>
<MediaQuery query="(max-device-width: 1224px)">
<MobileIndex />
</MediaQuery>

在chrome的调式工具里,从react的插件看到

我需要手动勾选matches才会出效果,但是后来重新npm start了一次也可以出效果。于是觉得有些诡异….
后来查看官方文档,发现以上的方式属于Using CSS Media Queries,另外还有一种方式Using Properties。至于这两个有什么区别呢,官方文档有给出Properties的详细介绍,翻译出来大概就是这种方式能符合reac的风格,所以首推。
代码如下:
1
2
3
4
5
6
<MediaQuery minDeviceWidth={1224}>
<PCIndex />
</MediaQuery>
<MediaQuery maxDeviceWidth={1224}>
<MobileIndex />
</MediaQuery>

2.关于组件
因为我在安装react-router的时候时4.2.0的版本,去node_modules的react-router查看,可以看见并没有组件,但是2.0的版本就有。经过各种百度发现组件搬家了,它的依赖变成了react-router-dom,所以只需要再安装一个react-router-dom就好啦~

5月17日 补充昨日份还有一个react的问题

1.因为是用create-react-app命令创建的项目,所以图片资源路径写法和手动配置webpack那种不一样。最开始真的急死我了,不过是相对路径还是绝对路径怎么写就是不对。后来把images文件移到public文件夹下,再src引用也不知道如何操作做,但是看见在public里的index.html在引用public文件下的icon的时候是这样用的

我就效仿这个在src文件夹下面的js文件里引用,简直不敢相信我的眼睛!还是不行=。= ,后来去查官方文档资源怎么引入,才发现可以如下使用

5月22日

1.关于preventDefault()方法
定义和用法:
取消事件的默认动作
语法:
event.preventDefault()
说明:
该方法将通知 Web 浏览器不要执行与事件关联的默认动作(如果存在这样的动作)。例如,如果 type 属性是 “submit”,在事件传播的任意阶段可以调用任意的事件句柄,通过调用该方法,可以阻止提交表单。注意,如果 Event 对象的 cancelable 属性是 fasle,那么就没有默认动作,或者不能阻止默认动作。无论哪种情况,调用该方法都没有作用。

2.在react里遇到过{…getFieldProps}的用法,但是不了解三点的意义
后来查询过后发现三个点是es6的一个特色叫对象展开运算符。
用法如下:
用es6的展开运算符

1
2
3
var arr1 = [1,2,3];
var arr2 = [...arr1,4,5,6];
console.log(arr2) //1,2,3,4,5,6

用push加展开运算符

1
2
3
4
var arr1 = [1,2,3];
var arr2 = [4,5,6];
arr1.push(...arr2);
console.log(arr1) //1,2,3,4,5,6

普通运算

1
2
3
var arr1 = [1,2,3];
arr1.push(4,5,6);
console.log(arr1) //1,2,3,4,5,6

也可以用在解构赋值

1
2
3
4
let [arg1,arg2,...arg3] = [1,2,3,4,5]
arg1//1
arg2//2
arg3//3,4,5

注意:在解构赋值中,展开运算只能在最后一个,如果在中间会报错

5月24日
1.关于调试的时候组件的报错
在我的代码中,link组件报错主要有两方面的原因。
(1).在使用link的时候,必须带上它的to属性,否则会报错(作为一个链接,必须有一个to属性,代表链接地址。这个链接地址是一个相对路径)
(2).使用了link子组件,在父组件被引用的时候,必须由BrowserRouter组件包裹起来,否则也会报错