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
渲染多个组件:
jsx1
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。jsx1
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 的发展方向,以及了解最新的技术模式,后续也会跟进更新相关笔记