代码之家  ›  专栏  ›  技术社区  ›  ashish singh

功能和功能组件之间的反应差异?

  •  0
  • ashish singh  · 技术社区  · 4 年前

    这不是为了行为,而是为了语法。

    两者的语法都是一样的,我可以很好地创建一个随机函数,它接受一个名为props的参数,但React会接受它并用这个函数做它的虚拟DOM吗?或者它可能正在检查该函数是否返回JSX,但这种检查是什么时候发生的?

    由于react只是一个库,何时静态区分哪些函数是组件,哪些函数不是组件?

    任何对文档的参考都会有所帮助。

    0 回复  |  直到 4 年前
        1
  •  1
  •   kca    4 年前

    React不进行任何静态分析来确定函数是否为组件。

    相反,React会做到 “这是虚拟DOM的东西” (以及所有其他魔法 lifecycles ) 如果函数返回有效的React元素

    React抛出一个错误-函数没有返回React元素。

    https://reactjs.org/docs/components-and-props.html :

    此函数是一个有效的React组件,因为它接受带有数据的单个props(代表属性)对象参数,并返回一个React元素。我们将这些组件称为函数组件,因为它们实际上是JavaScript函数。

    更详细地说。。。

    从技术上讲,React根本不需要任何功能或类组件。

    使用函数

    考虑这个没有任何组件或功能的示例:

    import React from 'react';
    import ReactDOM from 'react-dom';
    
    ReactDOM.render(
      React.createElement( 'div', null, [
          React.createElement( 'h1', null, 'React without any functions' ),
          React.createElement( 'p', null, 'Technically you don\'t need to pass functions to React.' ),
      ]),
      document.getElementById('root')
    );
    

    这很快就会变得麻烦。

    因此,可以使用 返回这些部分的函数,例如:

    const Headline = function(){
      return React.createElement( 'h1', null, 'React with "factory functions"' );
    };
    
    const Content = function(){
      return React.createElement( 'p', null, 'You might want to separate stuff using functions.' );
    };
    
    const Page = function(){
      return React.createElement( 'div', null, [
        Headline(),
        Content()
      ]);
    };
    
    ReactDOM.render(
      Page(),
      document.getElementById('root')
    );
    

    请注意,这些只是普通的javascript函数,根本没有“魔力”。

    如果您的函数没有返回有效的ReactElement,那么React只会抛出一个错误,例如:

    const Page = function(){
      return { notAValidReactElement: 'this is not a valid react element' };
    };
    
    ReactDOM.render(
      Page(),  // ---> Uncaught Error: Objects are not valid as a React child ...
      document.getElementById('root')
    );
    

    React“组件”类型

    但这并不是最优的,例如所有 .createElement() 方法仍然总是同时执行。

    React的人也有类似的想法,所以React接受了一个函数名 像 type 参数(而不是例如。 'h1' ),并像回调一样使用该函数,以便React可以决定例如该函数是否 实际需要执行,或者可以跳过:

    const Page = function(){
      return React.createElement( 'div', null, [
        React.createElement( Headline, null, [] ),
        React.createElement( Content, null, [] ) 
      ]);
    }
    

    这些功能仍然与以前相同。它们之所以有效,是因为我们编写它们是为了让它们返回正确的值。

    事实上,这或多或少是关于这个话题的全部故事,但人们可能也会困惑于我为什么是 谈论 React.createElement( Page, ... ,而我们通常使用类似的东西 <Page>...

    所以

    JSX

    人们可能会想到缩短 React.createElement 一位,用于较少的键入,例如:

    const CE = function( type, props, childs ){
      return React.createElement( type, props, childs );
    };
    
    ReactDOM.render(
      CE( 'div', null, [
          CE( 'h1', null, 'React without any functions' ),
          CE( 'p', null, [
          CE('b', null, 'Nice'),
          ' if we can shorten the code a bit.',
        ] ),
      ]),
      document.getElementById('root')
    );
    

    幸运的是,聪明人已经有了这个想法,所以你可以使用JSX,例如:

    ReactDOM.render(
      <div>
        <h1>React without any functions</h1>
          <p>
          <b>Even nicer: </b>
          we can just use JSX!
        </p>
      </div>,
      document.getElementById('root')
    );
    

    这只是一种不同的语法,在构建时会转换为javascript。

    (也许也可以看看 Hyperscript 用于比较和背景了解。)