13 Commits

Author SHA1 Message Date
Lewis Llobera
687c4ebf21 Change arrow functions to function declarations (#8412)
- The JavaScript template uses a function declaration to define the component, the TypeScript template and a page of the documentation used arrow functions. Changed it to use function declarations for consistency and readability.
2020-02-03 15:28:39 +01:00
Rohit Singhal
3190e4f4a9 Handle service worker error in Firefox (#8272)
* Handle service worker error in Firefox

See https://bugzilla.mozilla.org/show_bug.cgi?id=1429714 for more details.

* Update serviceWorker.js
2020-01-31 16:09:19 +01:00
Martin Litvaj
1959131423 Fix robots.txt for TS (#8403) 2020-01-31 12:55:05 +01:00
Ian Sutherland
d7c68420f7 Publish
- babel-plugin-named-asset-import@0.3.6
 - babel-preset-react-app@9.1.1
 - cra-template-typescript@1.0.1
 - cra-template@1.0.1
 - create-react-app@3.3.1
 - eslint-config-react-app@5.2.0
 - react-app-polyfill@1.0.6
 - react-dev-utils@10.1.0
 - react-error-overlay@6.0.5
 - react-scripts@3.3.1
2020-01-30 21:05:43 -07:00
Retsam
dada03574a Remove React.FC from Typescript template (#8177)
This removes `React.FC` from the base template for a Typescript project.

Long explanation for a small change: 

`React.FC` is unnecessary: it provides next to no benefits and has a few downsides.  (See below.)  I see a lot of beginners to TS+React using it, however, and I think that it's usage in this template is a contributing factor to that, as the prominence of this template makes it a de facto source of "best practice".  

### Downsides to React.FC/React.FunctionComponent

##### Provides an implicit definition of `children`

Defining a component with `React.FC` causes it to implicitly take `children` (of type `ReactNode`).  It means that all components accept children, even if they're not supposed to, allowing code like:

```ts
const App: React.FC = () => { /*... */ };
const Example = () => {
	<App><div>Unwanted children</div></App>
}
```

This isn't a run-time error, but it is a mistake and one that would be caught by Typescript if not for `React.FC`. 

##### Doesn't support generics.
I can define a generic component like:
```ts
type GenericComponentProps<T> = {
   prop: T
   callback: (t: T) => void
}
const GenericComponent = <T>(props: GenericComponentProps<T>) => {/*...*/}
```

But it's not possible when using `React.FC` - there's no way to preserve the unresolved generic `T` in the type returned by `React.FC`.

```ts
const GenericComponent: React.FC</* ??? */> = <T>(props: GenericComponentProps<T>) => {/*...*/}
```

##### Makes "component as namespace pattern" more awkward.
It's a somewhat popular pattern to use a component as a namespace for related components (usually children):

```jsx
<Select>
	<Select.Item />
</Select>
```

This is possible, but awkward, with `React.FC`:

```tsx
const  Select: React.FC<SelectProps> & { Item: React.FC<ItemProps> } = (props) => {/* ... */ }
Select.Item = (props) => { /*...*/ }
```

but "just works" without `React.FC`:

```tsx
const Select = (props: SelectProps) => {/* ... */}
Select.Item = (props) => { /*...*/ }
```

##### Doesn't work correctly with defaultProps

This is a fairly moot point as in both cases it's probably better to use ES6 default arguments, but...

```tsx
type  ComponentProps = { name: string; }

const  Component = ({ name }: ComponentProps) => (<div>
	{name.toUpperCase()} /* Safe since name is required */
</div>);
Component.defaultProps = { name: "John" };

const  Example = () => (<Component />) /* Safe to omit since name has a default value */
```
This compiles correctly.  Any approach with `React.FC` will be slightly wrong: either `React.FC<{name: string}>` will make the prop required by consumers, when it should be optional, or `React.FC<{name?: string}>` will cause `name.toUpperCase()` to be a type error.  There's no way to replicate the "internally required, externally optional" behavior which is desired.

##### It's as long, or longer than the alternative: (especially longer if you use `FunctionalComponent`):
Not a huge point, but it isn't even shorter to use `React.FC` 
```ts
const C1: React.FC<CProps> = (props) => { }
const C2 = (props: CProps) => {};
```

### Benefits of React.FC

##### Provides an explicit return type

The only benefit I really see to `React.FC` (unless you think that implicit `children` is a good thing) is that it specifies the return type, which catches mistakes like:

```ts
const Component = () => {
   return undefined; // components aren't allowed to return undefined, just `null`
}
```

In practice, I think this is fine, as it'll be caught as soon as you try to use it:

```ts
const Example = () => <Component />; // Error here, due to Component returning the wrong thing
```

But even with explicit type annotations, `React.FC` still isn't saving very much boilerplate:

```ts
const Component1 = (props: ComponentProps): ReactNode => { /*...*/ }
const Component2: FC<ComponentProps> = (props) => { /*...*/ }
```
2020-01-22 13:32:49 -08:00
Tom Valorsa
94932bedc0 Allow additional package keys and add blacklist (#8082) (#8219) 2020-01-12 14:10:03 +02:00
Alex Guerra
c03bb366e0 Replace favicon in templates (#8194)
The old favicon was the same as the official react documentation, which is a minor annoyance during development when trying to find the tab you want. The new favicon is just the old with inverted colors.

Closes #7957
2019-12-30 13:53:00 -06:00
Ian Schmitz
1a66971f9e Bump dependencies (#8024) 2019-11-24 15:48:15 -08:00
Ben Blank
5d24a5e88f Prefix apple-touch-icon links with PUBLIC_URL. (#8005) 2019-11-24 13:54:02 +02:00
Ian Schmitz
211694a8a2 Fix CI (#7951) 2019-11-08 18:54:16 -08:00
RJ Morgan
8a1ee2f7a5 Make JavaScript and TypeScript templates consistent (#7944) 2019-11-06 17:30:20 -07:00
Kent C. Dodds
2de57fe15a Add @testing-library to the default templates (#7881) 2019-10-29 14:36:55 -07:00
Brody McKee
4c0c81953d Add template support (#7716)
* Add template support

* Update templates version check

* Update TypeScript template README
2019-10-24 15:17:41 -07:00