React随笔2

1、React.PureComponent 与 React.Component 完全相同,但是在shouldComponentUpdate()中实现时,使用了 props 和 state 的浅比较。

  注意:

  React.PureComponent 的 shouldComponentUpdate() 仅对对象进行浅比较。 如果这些包含复杂的数据结构,它可能会在更深层数据差异比较时发生判断偏差。 所以扩展 PureComponent 只能用于具有简单 props 和 state 的组件,或者在知道深层数据结构已更改时使用forceUpdate() 来强制更新的组件。 或者,考虑使用不可变对象来帮助嵌套数据的快速比较。

再者,React.PureComponent 的 shouldComponentUpdate() 方法跳过了整个组件子树的 props 更新。所以确保所有的子组件也是“pure”。

2、forEach与map的区别与用法

  1)相同点

    1.1.都是循环遍历数组中的每一项

    1.2.每次执行匿名函数都支持三个参数,参数分别为item(当前每一项),index(索引值),arr(原数组)

    1.3.匿名函数中的this都是指向window

    1.4.只能遍历数组

  2)不同点

    1.1.map()会分配内存空间存储新数组并返回,forEach()不会返回数据。

    1.2.forEach()允许callback更改原始数组的元素。map()返回新的数组。

//forEach的demo
let arr1 = [0,2,4,6,8];
let newArr1 = arr1.forEach(function(item,index,arr1){
   arr1[index] = item/2; 
    return item/2; //即使return也不会返回新数组
},this);
console.log(arr1);  //[0, 1, 2, 3, 4]  改变了原数组
console.log(newArr1);  //undefined, 不会返回新数组

//map的demo
let arr = [0,2,4,6,8];
let newArr = arr.map(function(item,index,arr){
        return item/2;  //会返回新数组
 },this);
console.log(arr);    //[0, 2, 4, 6, 8]    原数组不变
 console.log(newArr); //[0, 1, 2, 3, 4]   返回的新数组

3、React.Fragment

//React.Fragment 组件允许你在 render() 方法中返回多个元素,而无需创建额外的 DOM 元素:
render() {
  return (
    <React.Fragment>
      Some text.
      <h2>A heading</h2>
    </React.Fragment>
  );
}
//可以用简写的 <></> 语法来使用它
render() {
  return (
    <>
      Some text.
      <h2>A heading</h2>
    </>
  );
}

4、React.createRef

//React.createRef 创建一个 ref ,它可以通过 ref 属性附加到 React 元素
class MyComponent extends React.Component {
  constructor(props) {
    super(props);

    this.inputRef = React.createRef();
  }

  render() {
    return <input type="text" ref={this.inputRef} />;
  }

  componentDidMount() {
    this.inputRef.current.focus();
  }
}

5、React.Suspense 和 React.lazy

//React.lazy() 允许你定义动态加载的组件。 这有助于减少包大小,以延迟加载在初始渲染期间未使用的组件
//渲染 lazy 组件要求渲染树中有一个 <React.Suspense> 组件。这是你指定加载 indicator(指示器) 的方式。
//React.Suspense 允许你指定加载 indicator(指示器) ,以防下面树中的某些组件尚未准备就渲染。现在,延迟加载组件是 <React.Suspense> 支持的 唯一 用例:
// This component is loaded dynamically
const OtherComponent = React.lazy(() => import('./OtherComponent'));

function MyComponent() {
  return (
    // Displays <Spinner> until OtherComponent loads
    <React.Suspense fallback={<Spinner />}>
      <div>
        <OtherComponent />
      </div>
    </React.Suspense>
  );
}

6、React.forwardRef  https://www.jianshu.com/p/fac884647720

  Refs 使用场景

  • 处理焦点、文本选择或者媒体的控制
  • 触发必要的动画
  • 集成第三方 DOM 库
//React.forwardRef 接受渲染函数作为参数。React 将用 props 和 ref 作为两个参数来调用这个函数。此函数应返回 React 节点
const FancyButton = React.forwardRef((props, ref) => (
  <button ref={ref} className="FancyButton">
    {props.children}
  </button>
));

// You can now get a ref directly to the DOM button:
const ref = React.createRef();
<FancyButton ref={ref}>Click me!</FancyButton>;

//在上面的例子中,React 传递一个 ref 给 <FancyButton ref={ref}> 元素作为第二个参数传递给React.forwardRef 调用中的渲染函数。 该渲染函数将 ref 传递给 <button ref = {ref}> 元素。
//因此,在 React 附加 ref 后, ref.current 将直接指向 <button> DOM 元素实例。

  基本的使用:通过组件获得input的引用

import React, { Component, createRef, forwardRef } from 'react';

const FocusInput = forwardRef((props, ref) => (
    <input type="text" ref={ref} />
));

class ForwardRef extends Component {
    constructor(props) {
        super(props);
        this.ref = createRef();
    }

    componentDidMount() {
        const { current } = this.ref;
        current.focus();
    }

    render() {
        return (
            <div>
                <p>forward ref</p>
                <FocusInput ref={this.ref} />
            </div>
        );
    }
}
export default ForwardRef;

  如果子组件中用到了该方法,那么对应的高阶组件中也需要使用React.forwardRef方法

import React, { Component, createRef } from 'react';

//这是基础组件,需要使用React.forwardRef方法
const FocusInput = React.forwardRef((props, ref) => <input type="text" ref={ref} />);

//这是对应的高阶组件,也需要使用React.forwardRef方法
const bindRef = (WrappedComponent) => {
    const ConvertRef = (props) => {
        const { forwardedRef, ...other } = props;
        console.log(forwardedRef);
        return <WrappedComponent {...other} ref={forwardedRef} />;
    };
    // “ref”是保留字段需要用普通的字段来代替,传递给传入的组件
    return React.forwardRef((props, ref) => {
        console.log(ref);
        return <ConvertRef {...props} forwardedRef={ref} />;
    });
};

const FocusInputWithRef = bindRef(FocusInput);

class ForwardRef extends Component {
    constructor(props) {
        super(props);
        this.ref = createRef();
    }

    componentDidMount() {
        const { current } = this.ref;
        current.focus();
    }

    render() {
        return (
            <div>
                <p>forward ref</p>
                <FocusInputWithRef ref={this.ref} />
            </div>
        );
    }
}
export default ForwardRef;

7、插槽(Portals)

   Portals 提供了一种很好的方法,将子节点渲染到父组件 DOM 层次结构之外的 DOM 节点。

//通常来说,当你从组件的 render 方法返回一个元素时,它将被作为子元素被装载到最近父节点 DOM 中:
render() {
  // React 装载一个新的 div,并将 children 渲染到这个 div 中
  return (
    <div>
      {this.props.children}
    </div>
  );
}
//然而,有时候将子元素插入到 DOM 节点的其他位置会有用的:
render() {
  // React *不* 会创建一个新的 div。 它把 children 渲染到 `domNode` 中。
  // `domNode` 可以是任何有效的 DOM 节点,不管它在 DOM 中的位置。
  return ReactDOM.createPortal(
    this.props.children,
    domNode,
  );
}



原文地址:https://www.cnblogs.com/zhengyulu/p/12883335.html