React学习笔记 - 基础篇
React学习笔记 - 基础篇
首先声明在这里看到的很多内容都是官方文档中提到的,当然也加入了一些自己的总结
在react中一切都是js,我们使用jsx来渲染组件
React在渲染所有输入内容之前默认会进行转义,可以有效地防止XSS(cross-site-scripting, 跨站脚本)攻击。
JSX表示对象
Babel会将JSX转义成一个名为React.createElement()
函数调用。
以下写法相等:
1 | const element = ( |
1 | //React.createElement()会预先执行一些检查,以帮助你编写无错代码,实际上 创建了一个这样的对象: |
这些对象被称为 “React 元素”。它们描述了你希望在屏幕上看到的内容。React 通过读取这些对象,然后使用它们来构建 DOM 以及保持随时更新
所有 React 组件都必须像纯函数一样保护它们的 props 不被更改。
State 与 生命周期
对于State我们应该正确的使用setState({})对State的数据进行更新
我们不能直接修改State
错误:this.state.comment = 'Hello';
正确:this.setState({comment: 'Hello'});
构造函数是唯一一个可以给State直接赋值的地方,在其他地方直接修改的时候不会更新dom
State 的更新可能是异步的
出于性能考虑,React 可能会把多个 setState() 调用合并成一个调用
由于this.props和this.state可能会异步更新,所以不可以依赖他们的值来更新状态
解决上述问题的办法是将setState()的参数设置为一个函数,而不是一个对象,这个函数用上一个state作为第一个参数,将被应用的props作为第二个 参数
1 | this.setState((state, props) => ({ |
State 的更新会被合并
当你调用 setState() 的时候,React 会把你提供的对象合并到当前的 state。
数据是向下传递的(自上而下、单向)
组件可以将state作为props向下传递到它的子组件中
生命周期
componentDidMount()
方法会在组件已经被渲染到 DOM 中后运行
完整生命周期:
- 卸载挂载过程:
constructor()
componentWillMount()
componentDidMount()
componentWillUnmount()
- 更新过程:
componentWillReceiveProps(nexrProps)
shouldComponentUpdate(nextProps, nextState)
componentWillUpdate(nextProps, nextState)
componentDidUpdate(prevProps, prevState)
render()
- React新增生命周期(替代上述两个周期函数):
getDerivedStateFromProps(nextProps, prevState)
getSnapshotBeforeUpdate(prevProps, prevState)
事件处理
React中事件处理与DOM中的区别:
React事件的命名方式采用小驼峰,而不是纯小写
使用JSX语法的时候需要传入一个函数进行处理,而不是传入一个字符串
在React中不允许使用返回false的方式阻止默认行为,可以显式地使用preventDefault, 例如:
1 | //DOM: |
在javaScript中class不会默认绑定this,如果不进行手动绑定,那么当在handleClick中使用this时,this为undefined
手动绑定方法:
function.bind(this, arguments)
(e) => this.function(arguments, e)
条件渲染
在React中使用条件判断时可以使用if语句或者三目运算进行判定
可以使用 条件&&视图 的方式进行条件判断
当需要进行条件隐藏时,可以在render中返回一个null,组件就会隐藏, return null;时不会对元素进行渲染,且并不会影响生命周期
列表与key
渲染多个组件:
1
2
3
4
5const numbers = [1, 2, 3, 4, 5]
const listItems = numbers.map(item => <li>{item}li>)
ReactDOM.render(
<ul>{listItems}</ul>, document.getElementById('root')
);封装成基础列表组件
- 使用这种方式时要给每一个列表元素分配一个key,key 在兄弟节点之间必须唯一
- key帮助React识别哪些元素改变了,迫不得已没有唯一值时可以使用索引index当作key
表单
受控组件
在HTML中表单一般都是自己维护自己的state。并且根据用户的输入进行更新,但是在React中可变状态(mutable state)都存储在state中,并且只能通过使用setState()进行更新。
我们可以把上述两种结合起来,让React的state成为唯一的数据源,这样就可以在React的组件中对用户输入过程中表单发生的操作进行控制,被React这样控制的组件叫做受控组件
- 可以对输入组件的value与React的state值进行绑定,对组件的onChange事件进行绑定,对表单的onSubmit事件进行绑定
- 文件的input标签,由于value值是只读的,所以
<input type="file">
是一个非受控组件 - 当需要处理多个 input 元素时,我们可以给每个元素添加 name 属性,并让处理函数根据
event.target.name
的值选择要执行的操作。在受控组件上指定 value 的 prop 会阻止用户更改输入。如果你指定了 value,但输入仍可编辑,则可能是你意外地将value 设置为 undefined 或 null。1
2
3
4// 这里使用了 ES6 计算属性名称的语法更新给定输入名称对应的 state 值
this.setState({
[name]: value
});
当然其实React官方也提供了更方便的非受控组件方式,,在之后的学习中也会逐步跟进。
状态提升
状态提升在官方文档中给出的定义是:当多个组件需要反应相同的变化数据时,我们可以将共享状态提升到最近的共同父组件中去
在官方文档提供的华氏度与摄氏度即时转换的示例中,将子组件中input的value值与父组件传过来的props中的值进行绑定,在input的onChange事件中绑定了父组件的温度转换事件,将所有的值都传输给父组件,由父组件中定义的转换函数转换后,绑定在state的值中,随后再将值传输给父组件,实现了状态提升
我在这里说的可能有些复杂,具体示例可以查看官方文档 ,下文中会有内嵌的官方文档连接
在React的应用中,任何的数据都应该只有一个相对应的”唯一数据源“
组合与继承
- 包含关系:
- this.props.children可以用来获取放入标签的dom元素,然后直接将这些元素引入到render中,等同于Vue中的slot插槽
- 特例关系:
- 以Dialog为例,我们可以手动封装一个Dialog组件,将title与message都封装成组件属性,通过传入属性的方式进行组合复用。
React哲学
建议查看官方描述React哲学
个人感觉很有帮助,会提升代码的规范意识,对编写架构都很有帮助。
总结
用了两周时间第一次学完了React.js的基础知识。
在学习完第一遍React的基础知识以后我深刻体会到了为什么React现在依然会是很多大厂的首选语言,从生态上来说的确时Vue需要用时间来填补的,但是Vue对比React在有些方面例如插槽、数据传输等方面要更加简便易操作,各有千秋,各有好坏,对于React我的认知还很少,还会更多的了解学习FaceBook对React的发展方向,以及了解最新的技术模式,后续也会跟进更新相关笔记