美文网首页
React小记(一)

React小记(一)

作者: 小面包呀 | 来源:发表于2019-05-29 11:57 被阅读0次

    1. Props传递时导致Pure组件重新渲染

    若直接在render里面去声明参数来传递给子组件,那么当父组件触发重新渲染的时可能会导致Pure的子组件也被重新渲染(String, Number, Boolean, null, undefined除外)。

    const listArray = []
    export default class App extends React.Component {
      state = {
        isLogin: false
      }
    
      userInfo = {name: 'Evan'}
      
      changeState = () => this.setState({
        isLogin: !this.state.isLogin
      })
      
      // class fields
      showLog = () => console.log('show Log')
    
      render() {
        return (
          <div>
            <div onClick={this.changeState}
            >更新状态</div>
            {/* 会引发PureComponent重新渲染 */}
            <Child
              showLog={() => this.showLog()}
              userInfo={{name: 'Evan'}}
              list={[]}
            />
            {/* 推荐:改成引用的方式 */}
            <Child
              showLog={this.showLog}
              userInfo={this.userInfo}
              list={listArray}
            />
          </div>
        )
      }
    }
    

    建议改成引用的方式去传递

    2.key为索引的危害

    当使用数组下标为索引时,可能会使元素显示错误当信息,因此应该避免使用index作为key。

    export default class App extends React.Component {
      state = {
        list: [{id: 1},{id: 2}]
      }
    
      addItem = () => this.setState({list: [{id: this.state.list.length + 1}, ...this.state.list]})
    
      render() {
        return (
          <div>
            <button onClick={this.addItem}>add items</button>
            {/* 使用index作为key */}
            {
              this.state.list.map((v, i) => <div key={i}>
                <label>第{i + 1}个:</label><input />
              </div>)
            }
            <hr />
            {/* 使用id作为key */}
            {
              this.state.list.map((v, i) => <div key={v.id}>
                <label>第{i + 1}个:</label><input />
              </div>)
            }
          </div>
        )
      }
    }
    

    3. Fragments

    Fragments可以让我们减少一些不必要的DOM节点的添加,它还有一个短语法可以达到相同的效果,短语法不支持key这个参数。

    render() {
      return (
        // 正常写法,可以支持key
        <React.Fragment>
          <ChildA />
          <ChildB />
           {/* 短语法 */}
          <>
            <ChildA />
            <ChildB />
          </>
        </React.Fragment>
      );
    }
    

    4. 组件懒加载

    在React16版本中新增了一个组件懒加载的方式,通过React.lazy动态引入组件然后再用Suspense来包裹即可。
    Suspense用来暂停组件渲染直到React.lazy引入完成才开始渲染。

    const Child = React.lazy(() => import('./Child'));
    
    class App extends React.Component {
      childRefs = React.createRef();
      logRef = () => console.log(this.childRefs)
      render() {
        return (
          <React.Fragment>
            <button onClick={this.logRef}>Click Me</button>
            <React.Suspense fallback={<div>Loading...</div>}>
              <Child ref={this.childRefs}/>
            </React.Suspense>
          </React.Fragment>
        )
      }
    }
    
    export default App;
    

    5.关于refs

    除去原本的回调函数外,React在16版本引入了React.createRefReact.forwardRef两个方法用来处理ref,它们会返回一个对象,而所获得的实例都会被存储到该对象的current里。

    • React.createRef
      获取 子元素/组件 的ref,所绑定的实例会被存储到该ref的current
    export default class App extends React.Component {
      // 用来储存ref
      childRefs = React.createRef();
      logRef = () => console.log(this.childRefs)
      render() {
        return (
          <React.Fragment>
            <button onClick={this.logRef}>Click Me</button>
            {/* 把子组件实例关联到 childRefs 上*/}
            <Child ref={this.childRefs}/>
          </React.Fragment>
        )
      }
    }
    
    • forwardRef
      用来转发ref,由于函数组件没有实例,所以没有ref,如需在父组件里获取其子组件某个元素的ref,那么可以使用该方法。
    class App extends React.Component {
      // 用来储存ref
      childRefs = React.createRef();
      logRef = () => console.log(this.childRefs)
      render() {
        return (
          <React.Fragment>
            <button onClick={this.logRef}>Click Me</button>
            <FnChild ref={this.childRefs}/>
          </React.Fragment>
        )
      }
    }
    const FnChild = React.forwardRef((props, ref) => <div ref={ref}>我是函数组件</div>)
    

    相关文章

      网友评论

          本文标题:React小记(一)

          本文链接:https://www.haomeiwen.com/subject/micjtctx.html