React笔记(核心概念部分)

核心概念

1. JSX

  • JSX是javascript的语法扩展,让我们可以在JS中编写常规html代码,在JSX中可以在大括号{}内放置任何有效的javascript表达式。
  • JSX也是一个表达式,可以在iffor循环代码块中使用JSX。
  • 通过引号将属性值指定为字符串字面量,使用大括号将属性值指定为j s表达式。
  • React DOM 使用 camelCase(小驼峰命名)来定义属性的名称,而不使用 HTML 属性名称的命名约定。例如在JSX中class变为className。
  const name = 'Jade';
  const element = 

Hello, {name}

; ReactDOM.render( element, document.getElementById('root') );

2. props

  • 当 React 元素为用户自定义组件时,它会将 JSX 所接收的属性以及子组件转换为单个对象传递给组件,这个对象被称之为 “props”。
  • 组件无论是使用函数声明还是class声明,都不能修改自身的 props,props为只读。

3. State

  • state是组件私有化,且完全受控于当前组件,简单说,完全props,state在组件内可以随意修改。定义state应该在class构造函数constructor中,state可以传递给子组件,数据是向下流动。
  • 关于修改state,应该使用setState(),而不是直接赋值。
    • this.setState({name: 'Jade'}); //correct
    • this.state.name = 'jade'; // wrong
  • setState()为异步,多个setState()会合并为一个调用。所以最好不要依赖它们的值来更新下一个状态。
  • 关于异步的问题,可以让setState()接受一个函数来解决,该函数接受两个参数,用上一个 state 作为第一个参数,将此次更新被应用时的 props 做为第二个参数。

4. 事件处理

  • 不能通过return false;阻止默认行为,只能是e.preventDefault()

  • JSX中回调问题,事件回调必须绑定this,不然回调中thisundefined。原因在于js函数工作原理:

    const obj = {
        name: 'Jade',
        say: function () {
            console.log(this);
        }
    };
    const test = obj.say;
    
    obj.say(); // {name: "Jade", say: ƒ}
    test(); // undefined
    

    在js中,传递一个函数名给一个变量,然后在变量后加上()调用这个方法,此时方法内部的this的指向就丢失。在React中,OnClick其实就是一个中间变量,所以this会丢失。

  • 关于事件回调中this丢失的解决办法有以下:

    • 使用bind绑定this点击
    • 使用箭头函数定义事件回调 this.click = () => { //do something }
    • 使用箭头函数调用事件回调 this.click()}>点击
  • 事件传递参数的方法有两种,分别是通过箭头函数和bind,事件对象e会被视为第二个参数,不同的是,箭头函数的方式必须显式的传入e,bind则不需要,如下:

5. 表单

  • 受控组件:表单中存在一个input,其value值必须是我们设置在constructor构造函数中的state的值,通过onChange事件改变state中的值,最终形成一个循环的回路影响。
  • 非受控组件:非受控也就意味着我可以不需要设置它的state属性,而通过ref来操作真实的DOM。

6. 组件之间通讯

  • 父子通讯:

    • // Context 可以让我们无须明确地传遍每一个组件,就能将值深入传递进组件树。
      // 使用场景: 嵌套多层的组件,且每层组件可能都会用到某个变量
      // 缺点:导致组件的复用性降低
      const NameContext = React.createContext('Jade'); // 默认值‘Jade’
      class App extends React.Component {
        render() {
          return (
            // 使用Provider,将变量传递给下面的所有组件
              
              
            
          )
        }
      }
      
      class PageHeader extends React.Component {
        render() {
          // 中组件不用在手动传递了
          return 
        }
      }
        
      class UserName extends React.Component {
        
        static contentType = NameContext;
        render() {
          return 

      {this.context}

      } }
    • // 父子通讯主要通过props传递参数,数据自上而下流动,实现父子通讯
      class ChildrenComponent extends React.Component {
          constructor(props) {
              super(props);
          }
      
          render() {
              return (
                  {/* 接受从父组件传递而来的title */}
                  

      {this.props.title}

      ) } } class ParentComponent extends React.Component { constructor(props) { super(props); this.state = { title: '标题' } } render() { return ( {/* 将this.state.title传递给子组件 */} ) } }
  • 子父通讯:

    • class ChildrenComponent extends React.Component {
          constructor(props) {
              super(props);
              this.state = {
                name: 'children component'
              }
          }
      
          clickBtn() {
              // 调用父组件方法并将参数传递给父组件
              this.props.onClickChildren(this.state.name);
          }
      
          render() {
              return (
                  
              )
          }
      }
      
      class ParentComponent extends React.Component {
          constructor(props) {
              super(props);
          }
      
          // 子组件调用,val参数为子组件传递过来
          onClickChildren(val) {
              console.log(val); // children component
          }
      
          render() {
              return (
                  
      {/* 将onClickChildren()方法作为props传递给子组件 */}
      ) } }
  • 子子通讯:

    • eventBus
    • Redux

你可能感兴趣的:(React笔记(核心概念部分))