【React】最新版本18 源码遨游(三) Children

React Children


ReactChildren提供了许多处理 props.children的方法。本文将源码由上往下解析。

escape

function escape(key: string): string {
   
  const escapeRegex = /[=:]/g;
  const escaperLookup = {
   
    '=': '=0',
    ':': '=2',
  };
  const escapedString = key.replace(escapeRegex, function(match) {
   
    return escaperLookup[match];
  });

  return '$' + escapedString;
}

把key里面的:替换成=0:替换成=2,这样key作为reactId更安全。

escapeUserProvidedKey

const userProvidedKeyEscapeRegex = /\/+/g;
function escapeUserProvidedKey(text: string): string {
   
  return text.replace(userProvidedKeyEscapeRegex, '$&/');
}

把用户提供的所有/(单个或多个)后面都再添加一个/

getElementKey

function getElementKey(element: any, index: number): string {
   
  // 类型验证,并且元素的key不为空
  if (typeof element === 'object' && element !== null && element.key != null) {
   
    // 返回显示键,使用之前的escape方法保证安全性
    return escape('' + element.key);
  }
  // 索引决定的隐式键
  return index.toString(36);
}

生成一个可辨识元素的key。

mapIntoArray

function mapIntoArray(
  children: ?ReactNodeList,
  array: Array<React$Node>,
  escapedPrefix: string,
  nameSoFar: string,
  callback: (?React$Node) => ?ReactNodeList,
): number {
   
  const type = typeof children;

  if (type === 'undefined' || type === 'boolean') {
   
    如果children的类型是void或者布尔值,则认定无效,
    children = null;
  }

  let invokeCallback = false;

  if (children === null) {
   
    // 如果children为空,触发回调函数
    invokeCallback = true;
  } else {
   
    switch (type) {
   
      case 'string':
      case 'number':
        // children 的类型为string和number同样触发回调函数
        invokeCallback = true;
        break;
      case 'object':
        switch ((children: any).$$typeof) {
   
          // 如果children是一个ReactElement或者Portal,同样触发回调函数
          case REACT_ELEMENT_TYPE:
          case REACT_PORTAL_TYPE:
            invokeCallback = true;
        }
    }
  }

  if (invokeCallback) {
   
    const child = children;
    let mappedChild = callback(child);
    // 即使child只有一个,也将它作为数组对待
    // 这样children数量增加也不会变
    // 生成一个
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值