react基础学习

本文最后更新于:2023年12月5日 晚上

组件

函数组件 与 ES6 的 class 组件

注意: 组件名称必须以大写字母开头。

React 会将以小写字母开头的组件视为原生 DOM 标签。例如,<div /> 代表 HTML 的 div 标签,而 <Welcome /> 则代表一个组件,并且需在作用域内使用 Welcome

你可以在深入 JSX中了解更多关于此规范的原因。

组合组件

props

react 很灵活, 但是它有一个严格的规定:

所有 React 组件都必须像纯函数一样保护它们的 props 不被更改。

注: js 和 php 不一样, php 会写时复制, 而 js 对于数组或者对象永远都是地址引用, 理解下面的代码:

let obj = { a: "this is a", b: "this is b" };
function fn(obj) {
  obj.c = "this is c";
}
fn(obj);
console.log(obj); // {a: "this is a", b: "this is b", c: "this is c"}

如果一定要修改, 就是用组件自己私有的状态: state

state

拥有 sate 属性的组件就是有状态组件, 没有 sate 属性的组件就是无状态组件。

尽管 this.propsthis.state 是 React 本身设置的,且都拥有特殊的含义,但是其实你可以向 class 中随意添加不参与数据流(比如计时器 ID)的额外字段。

componentDidMount() {
    this.timerID = setInterval(
        () => this.tick(),
        1000
    );
}

出于性能考虑,React 可能会把多个 setState() 调用合并成一个调用。

因为 this.propsthis.state 可能会异步更新,所以你不要依赖他们的值来更新下一个状态。

例如,此代码可能会无法更新计数器:因为 counter 的更新依赖了 state 和 props

// Wrong
this.setState({
  counter: this.state.counter + this.props.increment,
});

要解决这个问题,可以让 setState() 接收一个函数而不是一个对象。这个函数用上一个 state 作为第一个参数,将此次更新被应用时的 props 做为第二个参数:

// Correct
this.setState((state, props) => ({
  counter: state.counter + props.increment,
}));

通过问自己以下三个问题,你可以逐个检查相应数据是否属于 state:

  1. 该数据是否是由父组件通过 props 传递而来的?如果是,那它应该不是 state。
  2. 该数据是否随时间的推移而保持不变?如果是,那它应该也不是 state。
  3. 你能否根据其他 state 或 props 计算出该数据的值?如果是,那它也不是 state。

数据是向下流动的

这通常会被叫做“自上而下”或是“单向”的数据流。任何的 state 总是所属于特定的组件,而且从该 state 派生的任何数据或 UI 只能影响树中“低于”它们的组件。

如果你把一个以组件构成的树想象成一个 props 的数据瀑布的话,那么每一个组件的 state 就像是在任意一点上给瀑布增加额外的水源,但是它只能向下流动。

组件的生命周期函数

事件

使用 JSX 语法时你需要传入一个函数作为事件处理函数,而不是一个字符串。

html 中: onClick=“fn()”

jsx 中: onClick={fn}

render() {
  return (
    <button onClick={this.handleClick} />
  );
}
// 如果 this.handleClick 需要传递参数的话

你必须谨慎对待 JSX 回调函数中的 this,在 JavaScript 中,class 的方法默认不会绑定 this。如果你忘记绑定 this.handleClick 并把它传入了 onClick,当你调用这个函数的时候 this 的值为 undefined

当事件函数中需要 this 时, 我们有两种处理方式:

  1. bind 绑定

  2. public class fields 语法

    class 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)来实现的。


react基础学习
http://blog.lujinkai.cn/前端/React/react基础学习/
作者
像方便面一样的男子
发布于
2020年12月6日
更新于
2023年12月5日
许可协议