jsx语法规则
- 定义虚拟DOM时,不要写引号。
- 标签中混入JS表达式时要用{ }。
- 样式的类名指定不要用class,要用className。
- 内联样式,要用style={{key:value}}的形式去写。
- 只有一个根标签
- 标签必须闭合
- 标签首字母
- )若小写字母开头,则将该标签转为html中同名元素,若html中无该标签对应的同名元素,则报错
- )若大写字母开头,react就去渲染对应的组件,若组件没有定义,则报错。
js语句和js表达式
一定注意区分:【js语句(代码)】与【js表达式】
1.表达式:一个表达式会产生一个值,可以放在任何一个需要值的地方
下面这些都是表达式:
- (1). a
- (2). a+b
- (3). demo(1)
- (4). arr.map()
- (5). function test () {}
2.语句(代码):
下面这些都是语句(代码):
- (1).if(){}
- (2).for(){}
- (3).switch(){case:xxx}
{ }中是放JS表达式!
模块与组件、模块化与组件化的理解
模块(当应用的js都以模块来编写的,这个应用就是一个模块化的应用)
- 理解:向外提供特定功能的js程序,一般就是一个js文件e
- 为什么要拆成模块:随着业务逻辑增加,代码越来越多且复杂。
- 作用:复用 js,简化js 的编写,提高js运行效率
组件(当应用是以多组件的方式实现的,这个应用就是一个组件化的应用)
- 理解:用来实现局部功能效果的代码和资源的集合(html/css/js/image等等)
- 为什么:一个界面的功能更复杂
- 作用:复用编码,简化项目编码,提高运行效率
组件实践
- 函数式组件(适用于简单组件的定义)
- class式组件(适用于复杂组件的定义)
记住前面说的,组件标签是大写开头哦
函数式组件
执行力ReactDOM.render(<MyComponent />,document.getElementById('test'))之后,发送了什么?
1.React解析组件标签,找到了MyComponent组件
2.发现组件是使用函数定义的,随后调用该函数,将返回的虚拟DOM转为真实DOM,随后出现在页面中。
函数式组件函数名就是组件名
同理,类式组件类名就是组件名
类式组件
执行了ReactDOM.render(<MyComponent />,document.getElementById('test'))之后,发送了什么?
1.React解析组件标签,找到了MyComponent组件。
2.发现组件是使用类定义的,随后new出来该类的实例,并通过该实例调用到原型上的render方法。3.将render返回的虚拟DOM转为真实DOM,随后呈现在页面中。
组件实例三大属性
1.state
实例讲解
构造函数中的this就是指向组件实例对象
只有通过组件实例调用的方法,方法中的this才不是undefined,而是指向实例对象。
如果渲染的时候在标签onClick属性中直接写this.方法,相当于直接把该方法拉出来赋给了onClick,当点击时是直接触发该方法本身而不是用组件实例去调用的。
类中的方法自动开启了局部的严格模式,所以类中方法的this为undefined。
但是呢,这个样子虽然可以唱成功让我们在方法中获取到组件实例对象
我们顺理成章就会想着用this.state.isHot=!this.state.isHot去修改isHot的值。
但打印出来发现值是改了可是react不认。
状态(state)不可直接更改,我们需要借助一个内置的API更改——setState
注意这里虽然是说是setState,但它进行的是一个更新操作而不是直接替换
所以我们可以使用setState灵活修改state中的部分值
在上面的程序中
构造器调用几次?
render调用几次?
方法changeWeather调用几次?
——我们可以在它们内部的第一行进行输出操作,然后我们就可以通过控制台查看输出情况获得答案
所以
构造器调用几次?——1次
render调用几次?——1+n次
方法changeWeather调用几次?——点几次调几次
触发方法时,是先调用changeWeather,再进行渲染render
虽然上面那样子写很标准且没什么毛病,但是通过上面一系列我们发现实在是太麻烦了,如果我们有很多个类中方法,构造器中内容将会变得非常累赘
其实我们可以大大精简上面的代码,根本不需要用到构造器,在类中赋值语句相当于直接给类添加属性。
所以我们不需要在构造器中初始化state,我们可以把它提到外面来
而方法也不能简单地直接像上面那样写,应该使用赋值语句的形式+箭头函数。
箭头函数的特点是,在箭头函数内调用this,它会从箭头函数外面寻找this。
这样子一操作,代码就变成了这样子:
理解
(1)state是组件对象最重要的属性,值是对象(可以包含多个key-value 的组合)
(2)组件被称为"状态机",通过更新组件的state来更新对应的页面显示(重新渲染组件)
注意点
1)组件中 render 方法中的this为组件实例对象
2)组件自定义的方法中 this 为 undefined,如何解决?
a.强制绑定this:通过函数对象的 bind()
b.箭头函数
3)状态数据,不能直接修改或更新,要通过setState
2.props
实例讲解
回顾...展开运算符的用法
原生js中不能使用...展开运算符展开对象,但可以使用花括号加展开运算符进行深拷贝
直接用赋值语句的话相当于改变指向,不等于复制赋值。
在babel+react的作用下,可以使用后{...对象} 展开对象,但是仅仅适用于标签属性的传递。
如果要对prop传值进行类型限定和默认值设置
(记得导包)
应像下面这样子在类里面设置:
函数式组件也可以使用props
如果要对函数组件props进行限制
则放在函数外面,直接对函数组件实例添加限制
理解
(1)每个组件对象都会有props(properties的简写)属性
(2)组件标签的所有属性都保存在 props 中
作用
(1)通过标签属性从组件外向组件内传递变化的数据
(2)注意:组件内部不要修改 props 数据·(因为是只读的)
props总结
1)内部读取某个属性值
this.props.name
2)对props中的属性值进行类型限制和必要性限制
第一种方式(React v15.5开始已弃用)
内置于React中,后进行改进,把prop-types库提取出来,减轻了React的重量
第二种方式(新):
使用prop-types库进行限制(需要引入prop-types库)
3)扩展属性:将对象的所有属性通过props传递
4)默认属性值
5)组件类的构造函数
3.refs与事件处理
理解
组件内的标签可以定义ref属性来标识自己
编码
有三种形式
(1)字符串形式的ref
注意这里是双引号
注意,这种方法已经要被废弃了,官方不推荐使用
(2)回调形式的ref
注意内联函数写法更新过程中会执行两次
可以通过定义成class的绑定函数解决(类绑定)
(3)createRef创建ref容器
React.createRef调用后可以返回一个容器,该容器可以存储被ref所标识的节点
但!该容器是"专人专用"的!
但!这个方法是当前React最常用也是最推荐使用的。