33

I've seen multiple examples of React components using Typescript:

class Foo extends React.Component<IProps, IState> {}

It seems there is no a clear convention when we don't use either the Props or the State.

People set these types as any, null,undefined,{}, void, etc.This is what I've seen so far:

  1. class Foo extends React.Component<null, null> {}
  2. class Foo extends React.Component<any, any> {}
  3. class Foo extends React.Component<{}, {}> {}
  4. class Foo extends React.Component<undefined, undefined> {}
  5. class Foo extends React.Component<void, void> {}
  6. class Foo extends React.Component<object, object> {}

What's the best way of doing it?

Update:

SOLUTION

Simply do - class Foo extends React.Component {} as prop and state are initialised to {}

jobmo
  • 835
  • 1
  • 9
  • 19

6 Answers6

21

As answered for this question, you can use the React.FC<{}> class

const MyStatelessComponent : React.FC<{}> = props =>
    <div>{props.children}</div>

Or if your markup gets bigger:

const MyStatelessComponent : React.FC<{}> = props => {

    {/*  Some code here */}
    return <div>{props.children}</div>

}
Leone
  • 3,258
  • 3
  • 22
  • 28
  • 1
    `React.SFC<{}>` can as well be refactored to `React.FC<{}>` or `React.FunctionComponent<{}>` since hooks introduced State in functional components. – iamcastelli Apr 09 '19 at 22:56
  • 2
    If you are using TS and it is complaining about `FC<{}>`, you can reduce it to just `FC` without the angle and curly brackets. Working example: `const MyComponent: FC = () => { /* code and tsx here */ }` – Steverino Mar 23 '22 at 17:06
18

From https://github.com/DefinitelyTyped/DefinitelyTyped/blob/15b7bac31972fbc081028937dfb1487507ca5fc9/types/react/index.d.ts#L199-L200

interface Component<P = {}, S = {}> extends ComponentLifecycle<P, S> { }

Props and state are initialised to {}, so for a component with no state nor prop we can simply do:

class Foo extends React.Component {} 
jobmo
  • 835
  • 1
  • 9
  • 19
14

According to this guideline and my exp, I would say :

  1. class Foo extends React.Component<null, null> {} when you know you will not recieve props nor state
  2. class Foo extends React.Component<any, any> {} when you know you will recieve props and state but you really don't care what they look like
  3. class Foo extends React.Component<{}, {}> {} never saw, seems strange
  4. class Foo extends React.Component<undefined, undefined> {} same as null, it's up to you. I see more often null than undefined
  5. class Foo extends React.Component<void, void> {} bad idea, since seems to be reserved for functions return (when you do not expect one)

Other opinions are welcomed

soywod
  • 4,377
  • 3
  • 26
  • 47
  • I´ve seen some people having problems with `void` as a change in a recent version initialises the props to {} – jobmo Jun 25 '17 at 14:51
  • 1
    If I used `null` then I get this error: *Type '{}' is not assignable to type 'null'* – Al.G. Apr 01 '18 at 18:06
  • @Al.G. same here. Obviously missing out the angle brackets is the best if you have neither props nor state,but if you have one or the other, I think `{}` is the best option – Andy Apr 22 '20 at 09:29
8

You can use VoidFunctionComponent for stateless ans propless components (without state ana props):

const MyComponent: React.VoidFunctionComponent = () => {
  ...
}
2

I always create a props Interface for each component, even if it's blank. It keeps things consistant and allows me to easily add props later if needed.

Interface FooProps { }

class foo extends React.Component<FooProps, any> {
}
SteveKitakis
  • 162
  • 2
1

Stateful(class based components) & Stateless components there's a lot of conceptions on the internet about when use one or another, I've grasped these concepts using this list (before have practical experience):

Stateless

  1. Are concerned with how things look.
  2. May contain both presentational and container components** inside, and usually have some DOM markup and styles of their own.
  3. Often allow containment via this.props.children.
  4. Have no dependencies on the rest of the app, such as Flux actions or stores.
  5. Don’t specify how the data is loaded or mutated.
  6. Receive data and callbacks exclusively via props.
  7. Are written as functional components

Examples: Menu, UserInfo, List, SideBar.

Stateful

  1. Are concerned with how things work.
  2. May contain both presentational and container components** inside but usually don’t have any DOM markup of their own except for some wrapping divs, and never have any styles.
  3. Provide the data and behavior to presentational or other container components.
  4. Call Redux actions and provide these as callbacks to the presentational components.

Examples: UserPage, FollowersSidebar, ArticlesContainer.

Yuri Pereira
  • 1,945
  • 17
  • 24
  • Thanks for your answer but I meant what of the examples I put is the right way of doing it. I´ve edited the question to make it clearer – jobmo Jun 24 '17 at 17:31