这里只是对自己的学习进行一次总结,也是为了让自己以后如果长时间不使用快速记忆起来的笔记,如果想要学习,还是去官网看文档比较好一些。、
注意 下面的代码的 script标签的type类型都为 “text/babel”
目录
一、无状态组件
二、函数式声明
三、this以及事件对象
四、操作dom元素
五、父子组件传值
六、在浏览器中支持import export
一、 无状态的组件
只是普通的变量是没有状态的, 只有组件才有状态或无状态
react是单向数据流
状态其实就是让数据驱动视图的响应式数据
1 let a = ' 这里是div元素111 ' ;
2
3 setTimeout(() => {
4 console.log(' 函数执行了 ' );
5 a = ' 改变之后的值 '
6 },2000 );
7
8 const element = (
9 {a}
10 );
11
12 ReactDOM.render(
13 element,
14 document.getElementById(' app ' )
15 )
如果你学习过vue的话,那种双向数据绑定用的 Object.defineProperty() 叫数据劫持,然后用了订阅发布(观察者)那种模式,数据改变之后,会驱动着视图去改变
react必须要通过 setState() 这个组件的实例化对象去调用去改变自身的state才会去驱动视图是改变的,所以上面的那种就算数据改变了,但是视图是没有进行改变的。
看下面的es6的这种写法
1 class Element extends React.Component{
2 constructor() {
3 super();
4 this .state = { // 只有在state里面的内容才是有无状态的
5 a: ' 这里是div元素 '
6 };
7
8 setTimeout(() => {
9 this .setState({ // 这里必要要用 setState这个方法来改变值才会驱动视图去改变 如果 this.state.a = 'sdfsd' 这样是不会驱动视图去改变的
10 a: ' 改变之后的值 '
11 })
12 }, 1000 )
13 }
14 render() {
15 return (
16
17 {this .state.a}
18
19 );
20 }
21 }
22
23 ReactDOM.render(
24 ,
25 document.getElementById(' app ' )
26 )
二、 函数式声明
其实之前一直都是使用的变量去指代html元素,没有使用过 class 那种,现在先使用ES5的写法去写一写什么是函数式声明。
先看一下之前的写法吧
1 const Head = (
2 Head头部
3 );
4 const Foot = (
5 底部
6 );
7 const element = (
8
9 {
10 Head
11 }
12
Element内容
13 {
14 Foot
15 }
16
17 );
18
19 ReactDOM.render(
20 element,
21 document.getElementById('app')
22 )
函数式声明是什么样子的呢
1 const Head = function () {
2 return (
3 Head头部
4 )
5 };
6 const Foot = function () {
7 return (
8 底部
9 )
10 };
11 const Element = function () {
12 return (
13
14
15 Element内容
16
17
18 );
19 };
20
21 ReactDOM.render(
22 ,
23 document.getElementById('app'
)
24 )
可以很清晰的看到他们两个的区别,一个是使用变量来代表的,另外的一个是使用的组件形式代表的,开发中的写法都是使用ES6的class继承声明来写组件的
看一下函数声明的传值
1 const Head = function (props) {
2 return (
3 {props.title}
4 )
5 };
6 const Foot = function (props) {
7 return (
8 {props.con}
9 )
10 };
11 const Element = function () {
12 return (
13
14 <Head
15 title={'头部信息啊'}
16 />
17
Element内容
18 <Foot
19 con={'底部的内容啊'}
20 />
21
22 );
23 };
24
25 ReactDOM.render(
26 ,
27 document.getElementById('app')
28 )
这个样子和vue其实是挺像的,在标签上面写自定义的属性,子组件就可以接收到,等先这样看看,后面会使用class写的,class写起来感觉还容易理解一些。
注意: 函数式声明组件
1. 组件的首字母必须是大写
2. 不要使用H5新标签
下面看一个状态改变驱动视图的例子
1 const Head = function (props) {
2 return (
3 {props.title}
4 )
5 };
6 const Foot = function (props) {
7 return (
8 {props.con}
9 )
10 };
11
12 class Element extends React.Component{
13 constructor() {
14 super();
15 this .state = {
16 title: '头部信息',
17 con: '底部信息'
18 };
19
20 setTimeout(() => {
21 this .setState({
22 title: '头部信息改变'
23 })
24 },2000)
25 }
26 render() {
27 return (
28
29 <Head
30 title={this .state.title}
31 />
32
Element内容
33 <Foot
34 con={this .state.con}
35 />
36
37 );
38 }
39 }
40
41 ReactDOM.render(
42 ,
43 document.getElementById('app')
44 )
这样就可以和上面那种结合起来了,以后所有的组件都用class来写了,就不用function那种形式了。
三、 this以及事件对象
react组件中的this和事件对象的不同写法有的写法是需要绑定this的
1 class Element extends React.Component{
2 constructor() {
3 super();
4 }
5
6 btn() {
7 console.log(this ); // 可以看到这里打印的是 undefined
8 }
9
10 render() {
11 return (
12
13
title
14 this.btn}>按钮
15
16 );
17 }
18 }
19
20 ReactDOM.render(
21 ,
22 document.getElementById('app')
23 )
看到上面打印的this是undefined,下面有几种写法可以更正this指向实例化对象的
第一种 更正this和事件对象
1 class Element extends React.Component{
2 constructor() {
3 super();
4 this .btn = this .btn.bind(this ); // 在这里更正,官方推荐的也是这种写法
5 }
6
7 btn(e) {
8 console.log(this );
9 console.log(e.target)
10 }
11
12 render() {
13 return (
14
15
title
16 this.btn}>按钮
17
18 );
19 }
20 }
21
22 ReactDOM.render(
23 ,
24 document.getElementById('app')
25 )
需要注意的是上面的那种写法如果传递参数的话,那么事件对象就是最后一个没有对象参数的和js中的bind一样
1 class Element extends React.Component{
2 constructor() {
3 super();
4 this .btn = this .btn.bind(this ); // 在这里更正,官方推荐的也是这种写法
5 }
6
7 btn() {
8 console.log(this );
9 console.log(arguments) // 因为下面的函数传递了参数,这里第二个参数才是事件对象
10 }
11
12 render() {
13 return (
14
15
title
16 this.btn(1)}>按钮
17
18 );
19 }
20 }
21
22 ReactDOM.render(
23 ,
24 document.getElementById('app')
25 )
第二种 在行内bind
1 class Element extends React.Component{
2 constructor() {
3 super();
4 }
5
6 btn() {
7 console.log(this );
8 console.log(arguments)
9 }
10
11 render() {
12 return (
13
14
title
15 this.btn.bind(this, 1)}>按钮 // 直接写到行内,在这里改变this的指向,同样的问题,那个参数的事件对象是最后一个
16
17 );
18 }
19 }
20
21 ReactDOM.render(
22 ,
23 document.getElementById('app')
24 )
第三种 在一个函数里面执行它
1 class Element extends React.Component{
2 constructor() {
3 super();
4 }
5
6 btn(e) {
7 console.log(this );
8 console.log(arguments)
9 }
10
11 render() {
12 return (
13
14
title
15 {
16 this .btn(e,11);
17 }}>按钮
18
19 );
20 }
21 }
22
23 ReactDOM.render(
24 ,
25 document.getElementById('app')
26 )
第四种 改变函数的写法
1 class Element extends React.Component{
2 constructor() {
3 super();
4 }
5
6 btn = (e) => {
7 console.log(this );
8 console.log(e.target)
9 }
10
11 render() {
12 return (
13
14
title
15 this.btn}>按钮
16
17 );
18 }
19 }
20
21 ReactDOM.render(
22 ,
23 document.getElementById('app')
24 )
当然了这种方式如果要传递参数的话还是需要bind的。
四、 操作dom元素
如果想要在react中操作dom元素的话,有几种方法
第一种 直接使用js的方法
1 class Element extends React.Component{
2 constructor() {
3 super();
4
5 }
6
7 btn = () => {
8 const ele = document.querySelector('.h1');
9 console.log(ele);
10
11 };
12
13 render() {
14 return (
15
16
title
17 this.btn}>按钮
18
19 );
20 }
21 }
22
23 ReactDOM.render(
24 ,
25 document.getElementById('app')
26 )
第二种 通过事件对象
1 class Element extends React.Component{
2 constructor() {
3 super();
4
5 }
6
7 btn = (e) => {
8 console.log(e.target);
9 };
10
11 render() {
12 return (
13
14
title
15 this.btn}>按钮
16
17 );
18 }
19 }
20
21 ReactDOM.render(
22 ,
23 document.getElementById('app')
24 )
第三种 ref
和vue一样
1 class Element extends React.Component{
2 constructor() {
3 super();
4
5 }
6
7 btn = (e) => {
8 console.log(this .refs.abc) // 在这里获取它
9 };
10
11 render() {
12 return (
13
14
title // 这里定义一个字符串的名字
15 this.btn}>按钮
16
17 );
18 }
19 }
20
21 ReactDOM.render(
22 ,
23 document.getElementById('app')
24 )
不过最新版本的不建议上面的那种写法了,也是ref建议下面的写法
以后我们就可以用下面这种最常用的方式
1 class Element extends React.Component{
2 constructor() {
3 super();
4
5 }
6
7 btn = (e) => {
8 console.log(this .abc)
9 };
10
11 render() {
12 return (
13
14
{this .abc = abc}}>title
15 this.btn}>按钮
16
17 );
18 }
19 }
20
21 ReactDOM.render(
22 ,
23 document.getElementById('app')
24 )
第四种 ReactDOM.findDOMNode
1 class Element extends React.Component{
2 constructor() {
3 super();
4
5 }
6
7 btn = (e) => {
8 console.log(this .abc)
9
10 console.log(ReactDOM.findDOMNode(this .abc));
11 };
12
13 render() {
14 return (
15
16
{this .abc = abc}}>title
17 this.btn}>按钮
18
19 );
20 }
21 }
22
23 ReactDOM.render(
24 ,
25 document.getElementById('app')
26 )
ref如果标记的是组件,那么ref他就是组件,但是findDOMNode这种方式是获取DOM元素的,就算里面的参数是组件,也是获得DOM元素
五、 父子组件传值
核心思想
父组件给子组件传值 直接在组件上面添加属性就可以了 子组件通过props访问,得到 其实是构造函数实例化的时候传过去了
子组件给父组件传值 其实是父组件给子组件传一个函数,子组件调用的时候把 要传递的数据 放到 父组件传递过来的函数 的参数里面,然后父组件再去做他自己的操作
Item子组件
1 class Item extends React.Component {
2 constructor (props) {
3 super(props);
4 this .state = {
5 sub: this .props.data
6 }
7 }
8
9 componentWillReceiveProps(nextProps) {
10 console.log('执行了吗');
11 console.log(nextProps);
12 }
13
14 render() {
15 console.log('子组件打印this');
16 console.log(this );
17 console.log(this .props);
18
19 return (
20
21 Item组件
22 {this .state.sub.res}
23 this.props.supFn.bind(
this ,'子组件参数')} />
24 25 defaultValue="22"
26 onClick={() =>
{
27 this .props.supFn('参数2'
)
28 }}
29
30 />
31
32 );
33 }
34 }
父组件
1 class Main extends React.Component {
2 constructor() {
3 super();
4 this .superFn = this .superFn.bind(this );
5
6 }
7 state = {
8 data: {
9 res: '里面的数据'
10 }
11 };
12
13 superFn(a) {
14 console.log('父组件的函数');
15 console.log(`${a}`);
16 let data = {
17 res: '修改过后'
18 };
19 console.log(data);
20
21 this .setState({
22 data: data
23 })
24 }
25 render() {
26 return (
27
28 主页面
29 {this .state.data.res}
30 - this.superFn} data={
this .state.data} aaa="传值啊">
31
32 );
33 }
34 }
35
36 ReactDOM.render(
37 ,
38 document.getElementById('app')
39 )
六、在浏览器中支持import export
要在服务器环境下打开文件
在谷歌浏览器输入框中输入
然后就可以使用模块导出导出功能了
1 // 2.js
2 const a = 1;
3 const b = 2;
4
5 export default {a, b};
如果你看了我的文章有了一些收获我会非常高兴的,由于能力有限,文章有的部分解释的不到位,希望在以后的日子里能慢慢提高自己能力,如果不足之处,还望指正。