Skip to content

Instantly share code, notes, and snippets.

@hizo
Created July 27, 2018 09:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hizo/dff211877ce4b0a371b8116e7bb94cd9 to your computer and use it in GitHub Desktop.
Save hizo/dff211877ce4b0a371b8116e7bb94cd9 to your computer and use it in GitHub Desktop.
React data fetching HOCs
// The same api state machine as before
const withApiState = TargetComponent =>
class extends React.Component {
state = {
current: "idle"
};
apiState = {
pending: () => this.setState({ current: "pending" }),
success: () => this.setState({ current: "success" }),
error: () => this.setState({ current: "error" }),
idle: () => this.setState({ current: "idle" }),
isPending: () => this.state.current === "pending",
isSuccess: () => this.state.current === "success",
isError: () => this.state.current === "error",
isIdle: () => this.state.current === "idle"
};
render() {
return <TargetComponent {...this.props} apiState={this.apiState} />;
}
};
// A new HOC that fetches data via a passed `fetcher` prop
const withData = TargetComponent => {
class WithData extends React.Component {
static defaultProps = { mapper: f => f };
state = { data: null };
componentDidMount() {
this.fetchData();
}
fetchData = async () => {
const { apiState, fetcher, mapper } = this.props;
try {
apiState.pending();
const result = await fetcher();
const data = mapper(result);
this.setState({ data });
apiState.success();
} catch (e) {
apiState.error();
}
};
render() {
const { mapper, fetcher, ...rest } = this.props;
return (
<TargetComponent
{...rest}
data={this.state.data}
refetchData={this.fetchData}
/>
);
}
}
return withApiState(WithData);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment