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, ); }