5
votes

PropTypes are helpful for debugging because they show a warning when an expectations is not met. Beyond that, they're also nice to express the intention of how a component is meant to be used.

If I have a component that accepts a prop with a value that can be a promise, is there some way I can express that using PropTypes? I'm picturing either something direct like PropTypes.promise, or some way to express the concept of a "thenable" using building-block PropTypes.

Here is a highly simplified example to show my intended use case:

class SomeComponent extends Component {
  static propTypes = {
    someDataPromise: PropTypes.object // <-- can I be more expressive here?
  }

  state = {
    isLoading: false
  }

  async handleSubmit() {
    this.setState({ isLoading: true });

    const data = await this.props.someDataPromise;
    const response = await fetch(`/some/api/endpoint?data=${data}`);
    // do something with the response

    this.setState({ isLoading: false });
  }

  render() { /* ... */ }
}
3

3 Answers

10
votes

You could use an object with a particular shape e.g.

  PropTypes.shape({
     then: PropTypes.func.isRequired,
     catch: PropTypes.func.isRequired
  })
7
votes

Another way you can express that a prop is a Promise is to use PropTypes.instanceOf(). Important caveat: this only works if your promises are instances of the Promise class:

static propTypes = {
  someDataPromise: PropTypes.instanceOf(Promise)
}
2
votes

I don't think thats the way you should think in react. React is nothing more then a advanced template engine, which means you have a "state" of data and the view representing this state. Using a promise as property means you have a not defined state, which is really hard to representing in the aspect of a view component. This is the main problem of programming, you can do everything you want, but when you use a framework you should follow the philosophy of the framework.

Long story short, don't use promises as property. Ensure a valid deterministic state before you pass properties to a view component. Maybe a global state like redux with thunk or redux observables will help you to handle async information.