react 学习

157 阅读3分钟

核心概念

JSX简介

JSX 防止注入攻击:react 会自动把用户输入的数据转换成 字符串。React DOM 在渲染所有输入内容之前,默认会进行转义

元素渲染

React 元素是构成 React 应用的最小砖块,是一个普通的对象,开销小,它代表了_某个特定时刻_ 的 UI。

React 元素是不可变对象。一旦被创建,你就无法更改它的子元素或者属性。

React DOM 会 负责更新 DOM  来与 React 元素保持一致。

所以每次都是新创建一个 react 元素,然后传入 reactDOM.render(),然后 ReactDOM 负责比较上次和这次的元素状态,并且智只会更新一部分来达到效果

组件 & Props

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

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

事件处理

通常情况下,如果你没有在方法后面添加 (),例如 onClick={this.handleClick},你应该为这个方法绑定 **this**

class Toggle extends React.Component {
  constructor(props) {
    super(props);
    this.state = {isToggleOn: true};
    // 为了在回调中使用 `this`,这个绑定是必不可少的    
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    this.setState(state => ({      isToggleOn: !state.isToggleOn    })); 
  }
  render() {
    return (
      <button onClick={this.handleClick}>
        {this.state.isToggleOn ? 'ON' : 'OFF'}
      </button>
    );
  }
}

如果没有使用 bind ,那就或者在调用的地方使用箭头函数

class LoggingButton extends React.Component {
  handleClick() {
    console.log('this is:', this);
  }

  render() {
    // 此语法确保 `handleClick` 内的 `this` 已被绑定。
    return (
      <button onClick={() => this.handleClick()}>
        Click me
      </button>
    );
  }
}

/**
* 此语法问题在于每次渲染 LoggingButton 时都会创建不同的回调函数。
* 在大多数情况下,这没什么问题,但如果该回调函数作为 prop 传入子组件时,这些组件可能会进行额外的重新渲染。
* 我们通常建议在构造器中绑定或使用 class fields 语法来避免这类性能问题。
*/

列表 &  Key

一般 key 用元素的 id,不到万不得已,不用 index

 表单

受控组件上指定 value 的 prop 会阻止用户更改输入。如果你指定了 value,但输入仍可编辑,则可能是你意外地将value 设置为 undefinednull

下面的代码演示了这一点。(输入最初被锁定,但在短时间延迟后变为可编辑。)

ReactDOM.render(<input value="hi" />, mountNode);

setTimeout(function() {
  ReactDOM.render(<input value={null} />, mountNode);
}, 1000);

高级指引

context

context 提供了一种在组件之间共享值的方式

类似插槽(位置在API目录上面一点点):react.docschina.org/docs/contex…

1、const MyContext = React.createContect(defaultValue):
提供一个MyContext对象,可以给任意组件订阅。订阅的组件从【组件树中离自己最近的Provider】获取值,如果没有匹配到会显示默认值,如果没有默认值 消费组件的默认值不会生效**

2、MyContext.provider()

**_

  1. 当 Provider 的 value 值发生变化时,它内部的所有消费组件都会重新渲染。从 Provider 到其内部 consumer 组件(包括 .contextTypeuseContext)的传播不受制于 shouldComponentUpdate 函数,因此当 consumer 组件在其祖先组件跳过更新的情况下也能更新。(自我理解:不触发父组件的更新,但是可以更新自身的 context 数据)
  2. <MyContext.Provider value={/* 某个值 */}>
  3. 注意避免 本组就更新的时候影响子组件更新。   context会根据引用标识的value值的变化来决定渲染(本质是浅比较)

_

3、MyContext.consumer (函数式接收)

注意这种方法需要在中间使用一个函数来接收,其中 value 是 context

**

<MyContext.Consumer>
  {value => /* 基于 context 值进行渲染*/}
</MyContext.Consumer>

5、class.contextType(类接收)

**

  1. 挂载在 class 上的 contextType 属性可以接收 最近 Context 上的值。你可以在任何生命周期中用  this.context  访问到它,包括 render 函数中。

  2. 你只通过该 API 订阅单一 context。如果你想订阅多个,阅读使用多个 Context 章节

    class MyClass extends React.Component { static contextType = MyContext; render() { let value = this.context; /* 基于这个值进行渲染工作 */ } }

4、MyContext.displayName()

不太懂....还是看官网吧