Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Structuring react project with flow type for best type reusability

I've came into a problem where I have to re-type / re-define repeating types in my store / view / components files i.e. Think a view that takes in some store value and has a function that alters that value and this function is passed down to a component.

There is a lot of type re-usability happening here and I went on to research how to structure projects for this, but didn't find anything useful. What I did find is $PropertyType utility class, that led me to the following approach

// @flow
import React, {Component}
import OtherComponent from "./OtherComponent"

export type MyComponentProps = {
  something: string
}

export type MyComponentState = {
  something2: boolean
}

export type MyComponentActions = {
  check: (
    something2: $PropertyType<MyComponentState, 'something2'>,
    something: $PropertyType<MyComponentProps, 'something'>
  ) => string
}

class MyComponent extends Component<MyComponentProps, MyComponentState> {

  state = { something: /* comes from somewhere else i.e store */ false }

  check: $PropertyType<MyComponentActions, 'check'> = (something2, something) => something2 ? "Default" : something

  render() {
    return <OtherComponent foo={this.check} />
  }
}

This is a somewhat of useless example, but it shows the pattern I chose, this way OtherComponent can import these types i.e. for check function and use $PropertyType in it when it is specifying its foo prop type.

It works, but is extremely verbose, hence I wanted to ask community for alternative suggestions.

My main goal is to be able and re-use these types without the need to re-type them a lot in a clean manner.

like image 564
Ilja Avatar asked Jun 14 '18 16:06

Ilja


People also ask

Is there a recommended way to structure React projects?

There is no "best project architecture" that will fit with any project and coding style. But you should always structure your project. React doesn't follow any particular project structure, and the positive thing about this is that it allows us to make up a structure to suit our needs.

How can we achieve reusability in React?

Solution: We can use a custom hook that will allow us to reuse this toggle logic in both components, and in any new component added in the future.

What is the best folder structure for React?

The simplest folder structure for this case seems to be the “group files by their types” option mentioned in the React docs. This makes our lives easy: Components go in the components folder, hooks in the hooks folder, and contexts in the contexts folder.


1 Answers

I don't think there is a general answer to this problem and I cannot give you a definite answer here. I have been working with flow now extensively for 1,5 years and also together with React for a year now. Here are some tips for working with types.

1. Use type inference

Flow is really powerful when it comes to inferring types. Together with the following tips you can avoid making a lot of annotations. Flow will just figure out that things work. You can also make use of the typeof annotation to get the type of a value.

2. Model your domain with types not the interfaces of the components

This was mentioned in the comments already. Use types to model your domain. E.g. if you work with a component that displays a user, model the user object, not the interface of the component. You can then import the user type in the components that use it.

type User = { id: string, name: string };
type ProfilePropType = { user: User };

class Profile extends Component<ProfilePropType> {
  // ...
}

3. Use state management

Redux for example could help you with the types here. This will give you a structure for your domain types and also reduces how many props are passed around. Another blessing is GraphQL and Apollo Client / Relay.

4. Generate types programmatically

We are generating types from our Postgres schema via postloader in the backend and types for our GraphQL queries in the frontend. Currently we are working on generating types for react-semantic-ui from their documentation. After that there are not many types left to write ourselves. There are probably some tools around for your use case.

One last thing:

Types are verbose. Sometimes it is good to be explicit. The idea is that types reduce the time you spend searching for bugs by forcing you to be explicit about things. Often it is okay to redefine things. This will also lead to way better errors than using $PropertyType because Flow will give you two types that are incompatible instead of cryptic messages.

like image 80
Herku Avatar answered Oct 04 '22 06:10

Herku