Define non-arrow React functional component for TypeScript?

前端 未结 3 1409
面向向阳花
面向向阳花 2021-01-17 23:32

You can define a React functional component\'s types in TypeScript with this:

export const Component: React.FC = () => {
  return // Stuff
};


        
相关标签:
3条回答
  • 2021-01-17 23:47

    How do you do the same for a non-arrow function?

    import * as React from 'react';
    
    function NonFatArrow(): React.ReactElement {
        return (
          <>
            Non-fat-arrow function
          </>
        );
    }
    
    const FatArrow: React.FunctionComponent = _props => {
      return (
        <section>
          <NonFatArrow/>
        </section>
      );
    };
    
    

    Is there any practice difference?

    Stepping aside from React and Typescript, in ES6 a fat arrow function captures few things including this and will carry the capture along self. So if there are thousands of such functions then there will be overhead of captures.

    Coming back to React and Typescript, this is not used in React.FunctionComponent(s) however if Typescript transpiler of your choosing transpiles to ES6 then there will be fat arrow functions with captures.

    So it all depends on the chosen transpiler and its settings. With Typescript compiler, if you have "target": "es5" in tsconfig.json, then the FatArrow component will be transpiled into ES5 function. Changing the setting to "target": "es6" ensures FatArrow is transpiled to an arrow function. With Babel as transpiler your mileage may vary.

    0 讨论(0)
  • 2021-01-17 23:55

    There is better type support for some certain cases when you declare component with const. To understand these cases you can have a look at the React.FC type:

    type FC<P = {}> = FunctionComponent<P>;
    interface FunctionComponent<P = {}> {
        (props: PropsWithChildren<P>, context?: any): ReactElement | null;
        propTypes?: WeakValidationMap<P>;
        contextTypes?: ValidationMap<any>;
        defaultProps?: Partial<P>;
        displayName?: string;
    
    }
    

    Since react component (even function component) is a bit more than just a plain function - specifying precise type for component itself gives you better type inference:

    
    function FooAsFunc({ children }) { // children has 'any' type
      return 1234
    }
    
    const FooAsConst: React.FC = ({ children }) => {
      return 1234 // type error: typescript knows that 1234 is not valid react component return type
    }
    
    FooAsFunc.displayName = new Date()
    FooAsConst.displayName = new Date() // type error: 'displayName' suppose to be of a type string
    

    In the end, same type safety can be achieved with function declaration as well, but it just requires more code.

    0 讨论(0)
  • 2021-01-17 23:57

    If you want to use the full type of a function to type a non-arrow function, you can use something like this (typescript documentation) :

    let myAdd: (x: number, y: number) => number =
        function(x: number, y: number): number { return x + y; };
    

    In your case:

    const MyComponent: React.FC = function() {
      return <div></div>;
    };
    
    0 讨论(0)
提交回复
热议问题