• 欢迎大家分享资料!前往留言板评论即可!

React源码解析(一)

合宙 模组资料网 1年前 (2021-05-15) 215次浏览 已收录 0个评论 扫描二维码

React 主要文件架构 | 用法

  • React.js React入口文件

  • ReactBaseClass.js

    Component | PureComponent
    
  • ReactCreateRef.js
    createRef
    
  • forwardRef.js
    forwardRef // 提供挂载到子组件的ref
    
    // index.jsx
    import React from "react"
    
    const TargetComponent = React.forwardRef((props, ref) => (
    <input type="text" ref={ref} />
    ))
    
    class ForwardRef extends React.Component {
    constructor() {
      super()
      this.ref = React.createRef()
    }
    componentDidMount(){
      this.ref.current.value = "ref get value"
    }
    render() {
      return <div>
        <TargetComponent ref={this.ref} />
      </div>
    }
    }
    
    export default ForwardRef
    
  • ReactContext.js
    //  使用方式
    1. childContextType
    2. createContext
    // 使用示例
    import React from "react"
    import propTypes from "prop-types"
    
    const { Provider, Consumer } = React.createContext('default')
    
    class Context extends React.Component {
    constructor() {
      super()
      this.state = {
        childContext: '123',
        newContext: '456',
      }
    }
    
    getChildContext() {
      return { value: this.state.childContext }
    }
    
    render() {
      return <React.Fragment>
        <div>
          <label>childContext:</label>
          <input type="text" value={this.state.childContext}
            onChange={(e) => { this.setState({ childContext: e.target.value }) }} />
        </div>
        <Child2 />
        <div>
          <label>newContext:</label>
          <input type="text" value={this.state.newContext}
            onChange={(e) => { this.setState({ newContext: e.target.value }) }} />
        </div>
        <Provider value={this.state.newContext}>
          <Child1 />
        </Provider>
      </React.Fragment>
    }
    }
    
    function Child1() {
    return <Consumer>{value => <p>newContext:{value}</p>}</Consumer>
    }
    
    class Child2 extends React.Component {
    render() {
      return <p>childContext:{this.context.value}</p>
    }
    }
    
    Child2.contextTypes = {
    value: propTypes.string
    }
    
    Context.childContextTypes = {
    value: propTypes.string
    }
    
    export default Context
    
  • shared/ReactSymbols.js
    • Concurrentmode 降低子组件事件优先级(在浏览器有时间空袭那是才执行事件,有时间限制)
    // 版本
    "react": "16.7.0-alpha.2",
    "react-dom": "16.7.0-alpha.2",
    
    import React, { ConcurrentMode } from "react"
    import { flushSync } from "react-dom"
    import "./global.css"
    
    class Parent extends React.Component {
    constructor() {
      super()
      this.state = { 
        async: true,
        num: 1,
        length: 100
      }
    }
    componentDidMount() {
      this.interval = setInterval(() => {
        this.updateNum()
      }, 200)
    }
    componentWillUnmount() {
      if (this.interval) {
        clearInterval(this.interval)
      }
    }
    updateNum() {
      const newNum = this.state.num === 3 ? 0 : this.state.num + 1
      if (this.state.async) {
        this.setState({
          num: newNum
        })
      } else {
        flushSync(() => {
          this.setState({
            num: newNum
          })
        })
      }
    }
    render() {
      const children = []
      const { length, num, async } = this.state
      for (let i = 0; i < length; i++) {
        children.push(
          <div className="item" key={i}>
            {num}
          </div>
        )
      }
    
      return (
        <div className="main">
          <input
            type="text"
            value={length}
            onChange={e => flushSync(() => this.setState({ length: parseInt(e.target.value) }))}
          />
          async:{''}
          <input
            type="checkbox"
            checked={async}
            onChange={() => flushSync(() => this.setState({ async: !async }))}
          />
          <div className="warpper">{children}</div>
        </div>
      )
    }
    }
    
    export default () => (
    (<ConcurrentMode>
      <Parent />
    </ConcurrentMode>)
    )
    
    • Suspense 标签包裹下的所有组件全部加载完成,才会显示
    import React, { Suspense, lazy } from "react"
    
    const LazyComp = lazy(() => import("./lazy"))
    let data = ''
    let promise = ''
    function requestData() {
    if (data) return data
    if (promise) throw promise
    promise = new Promise(resolve => {
      setTimeout(() => {
        data = 'Data resolve'
        resolve()
      }, 2000)
    })
    throw promise
    }
    
    function SuspenseComp() {
    const data = requestData()
    return <p>{data}</p>
    }
    
    export default () => (
    <Suspense fallback="loading data...">
      <SuspenseComp />
      <LazyComp />
    </Suspense>
    )
    
  • ReactLazy.js
    import React, { Suspense, lazy } from "react"
    
    const LazyComp = lazy(() => import("./lazy"))
    
  • ReactHooks.js
    • useState

    • useEffect

    // componentDidMount componentDidUnMount
    useEffect(() => {
        console.log('component mount');
        return () => {
          console.log('component unmount');
        }
      }, [])
    
    // componentWillUpdate componentDidUpdate
    useEffect(() => {
        console.log('component update');
        return () => {
          console.log('unbind events');
        }
      })
    
  • ReactChildren.js

    export default{
    Children: {
    map,
      forEach,
      count,
      toArray,
      only,
    }}
    
  • others
    • memo.js

    提供类似PureComponent的功能

    • Fragment

    作为jsx最上层容器

    • StrictMode

    给所有子组件提供过时API的提醒

    • cloneElement

    克隆节点

    • createFactory

    对createElement的封装

    export function createFactory(type) {
      const factory = createElement.bind(null, type);
      factory.type = type;
      return factory;
    }
    

React 中导出的各种方法其实并没有提供具体的功能,大多是在组件外部添加了各种标记,真正的render行为是在ReactDOM中完成的


转载请注明原文链接:React源码解析(一)
喜欢 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址