刨根笔记--由antd开始的jsx渲染学习路线

JSX 仅仅只是 React.createElement(component, props, ...children) 函数的语法糖。简而言之就是用js去构建各种元素。
我想自定义一个Hook,来防止antd中input组件在回车键是误触发onFinish的校验,但是网上关于jsx元素作为函数参数传递的帖子很少,传进去容易,处理这个小东西就比较麻烦了,尝试了很多办法都报错
我在控制台打印了一下,看到el下有type key props
key没什么用,props只读,看了下el.type,是个函数

const useFormInput = (el: JSX.Element, pop?: SearchProps) => {
  console.log(el)
  return React.createElement(el.type, { ...el.props, ...pop, onPressEnter: (e: any) => e.preventDefault() })
}

然后顺着源码看到了antd中如何实现Input组件的(node_modules/antd/lib/input/input.js)

发现return的就是React.createElement()的结果
然后就去官网看看这个 createElement

React.createElement(
  type,
  [props],
  [...children]
)

然后看看源码
https://github.com/facebook/react/blob/main/packages/react/src/ReactElement.js#L30
 

export function createElement(type, config, children) {
   let propName;
 
   // Reserved names are extracted
   const props = {};
 
   let key = null;
   let ref = null;
   let self = null;
   let source = null;
 
   if (config != null) {
     if (hasValidRef(config)) {
       ref = config.ref;
 
       if (__DEV__) {
         warnIfStringRefCannotBeAutoConverted(config);
       }
     }
     if (hasValidKey(config)) {
       if (__DEV__) {
         checkKeyStringCoercion(config.key);
       }
       key = '' + config.key;
     }
 
     self = config.__self === undefined ? null : config.__self;
     source = config.__source === undefined ? null : config.__source;
     // Remaining properties are added to a new props object
     for (propName in config) {
       if (
         hasOwnProperty.call(config, propName) &&
         !RESERVED_PROPS.hasOwnProperty(propName)
       ) {
         props[propName] = config[propName];
       }
     }
   }
 
   // Children can be more than one argument, and those are transferred onto
   // the newly allocated props object.
   const childrenLength = arguments.length - 2;
   if (childrenLength === 1) {
     props.children = children;
   } else if (childrenLength > 1) {
     const childArray = Array(childrenLength);
     for (let i = 0; i < childrenLength; i++) {
       childArray[i] = arguments[i + 2];
     }
     if (__DEV__) {
       if (Object.freeze) {
         Object.freeze(childArray);
       }
     }
     props.children = childArray;
   }
 
   // Resolve default props
   if (type && type.defaultProps) {
     const defaultProps = type.defaultProps;
     for (propName in defaultProps) {
       if (props[propName] === undefined) {
         props[propName] = defaultProps[propName];
       }
     }
   }
   if (__DEV__) {
     if (key || ref) {
       const displayName =
         typeof type === 'function'
           ? type.displayName || type.name || 'Unknown'
           : type;
       if (key) {
         defineKeyPropWarningGetter(props, displayName);
       }
       if (ref) {
         defineRefPropWarningGetter(props, displayName);
       }
     }
   }
   return ReactElement(
     type,
     key,
     ref,
     self,
     source,
     ReactCurrentOwner.current,
     props,
   );
 }

发现最后return出的是reactElement()的结果

上源码
 

const ReactElement = function(type, key, ref, self, source, owner, props) {
   const element = {
     // This tag allows us to uniquely identify this as a React Element
     $$typeof: REACT_ELEMENT_TYPE,
 
     // Built-in properties that belong on the element
     type: type,
     key: key,
     ref: ref,
     props: props,
 
     // Record the component responsible for creating this element.
     _owner: owner,
   };
 
   if (__DEV__) {
     // The validation flag is currently mutative. We put it on
     // an external backing store so that we can freeze the whole object.
     // This can be replaced with a WeakMap once they are implemented in
     // commonly used development environments.
     element._store = {};
 
     // To make comparing ReactElements easier for testing purposes, we make
     // the validation flag non-enumerable (where possible, which should
     // include every environment we run tests in), so the test framework
     // ignores it.
     Object.defineProperty(element._store, 'validated', {
       configurable: false,
       enumerable: false,
       writable: true,
       value: false,
     });
     // self and source are DEV only properties.
     Object.defineProperty(element, '_self', {
       configurable: false,
       enumerable: false,
       writable: false,
       value: self,
     });
     // Two elements created in two different places should be considered
     // equal for testing purposes and therefore we hide it from enumeration.
     Object.defineProperty(element, '_source', {
       configurable: false,
       enumerable: false,
       writable: false,
       value: source,
     });
     if (Object.freeze) {
       Object.freeze(element.props);
       Object.freeze(element);
     }
   }
 
   return element;
 };

懂了吧

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值