react基础学习
组件
函数组件 与 ES6 的 class
组件
注意: 组件名称必须以大写字母开头。
React 会将以小写字母开头的组件视为原生 DOM 标签。例如,
<div />
代表 HTML 的 div 标签,而<Welcome />
则代表一个组件,并且需在作用域内使用Welcome
。你可以在深入 JSX中了解更多关于此规范的原因。
组合组件
props
react 很灵活, 但是它有一个严格的规定:
所有 React 组件都必须像纯函数一样保护它们的 props 不被更改。
注: js 和 php 不一样, php 会写时复制, 而 js 对于数组或者对象永远都是地址引用, 理解下面的代码:
1 | let obj = { a: "this is a", b: "this is b" }; |
如果一定要修改, 就是用组件自己私有的状态: state
state
拥有 sate 属性的组件就是有状态组件, 没有 sate 属性的组件就是无状态组件。
尽管 this.props
和 this.state
是 React 本身设置的,且都拥有特殊的含义,但是其实你可以向 class 中随意添加不参与数据流(比如计时器 ID)的额外字段。
1 | componentDidMount() { |
出于性能考虑,React 可能会把多个 setState()
调用合并成一个调用。
因为 this.props
和 this.state
可能会异步更新,所以你不要依赖他们的值来更新下一个状态。
例如,此代码可能会无法更新计数器:因为 counter 的更新依赖了 state 和 props
1 | // Wrong |
要解决这个问题,可以让 setState()
接收一个函数而不是一个对象。这个函数用上一个 state 作为第一个参数,将此次更新被应用时的 props 做为第二个参数:
1 | // Correct |
通过问自己以下三个问题,你可以逐个检查相应数据是否属于 state:
- 该数据是否是由父组件通过 props 传递而来的?如果是,那它应该不是 state。
- 该数据是否随时间的推移而保持不变?如果是,那它应该也不是 state。
- 你能否根据其他 state 或 props 计算出该数据的值?如果是,那它也不是 state。
数据是向下流动的
这通常会被叫做“自上而下”或是“单向”的数据流。任何的 state 总是所属于特定的组件,而且从该 state 派生的任何数据或 UI 只能影响树中“低于”它们的组件。
如果你把一个以组件构成的树想象成一个 props 的数据瀑布的话,那么每一个组件的 state 就像是在任意一点上给瀑布增加额外的水源,但是它只能向下流动。
组件的生命周期函数
事件
使用 JSX 语法时你需要传入一个函数作为事件处理函数,而不是一个字符串。
html 中: onClick=“fn()”
jsx 中: onClick={fn}
1 | render() { |
你必须谨慎对待 JSX 回调函数中的 this
,在 JavaScript 中,class 的方法默认不会绑定 this
。如果你忘记绑定 this.handleClick
并把它传入了 onClick
,当你调用这个函数的时候 this
的值为 undefined
。
当事件函数中需要 this 时, 我们有两种处理方式:
bind 绑定
public class fields 语法
1
2
3
4
5
6
7
8
9
10
11
12
13
14class LoggingButton extends React.Component {
// 此语法确保 `handleClick` 内的 `this` 已被绑定。
// 注意: 这是 *实验性* 语法。
handleClick = () => {
console.log("this is:", this);
};
// 注意 handleClick的写法, 如果 handleClick() {} 这么写是不对的
render() {
return <button onClick={this.handleClick}>Click me</button>;
}
}
// 或者 调用的时候使用箭头函数, 那么事件方法在定义的时候就可以写成 handleClick() {} 这种形式
// <button onClick={()=>this.handleClick()}>
推荐使用 public class fields 语法。
状态提升
因为 state 只能影响其及其”下面”的组件,如果想影响到”上面”的组件怎么办? 这就是状态提升, 实际上就是子组件给父组件通信。
实现方式和 vue 一样,通俗的来讲都是父组件定义方法, 这个方法一定是要传参的, 然后传递给子组件, 当子组件有数据修改,就通过this.props.event(val)
的方式激活父组件来执行方法。vue 中是通过this.$emit(event, i)
来实现的。