Source: react design patterns and best practices
By Michelle Bertolli
Publication time: the first edition in August 2018 (still new)
Use react refetch to simplify the api's code for getting data
const List = ({data: gists}) => { return ( <ul> {gists.map(gist => ( <li key={gist.id}>{gist.description}</li> ))} </ul> ) } const withData = url => Part => { return class extends Component { state = {data: []} componentDidMount() { fetch(url) .then(response => response.json ? response.json() : response) .then(data => this.setState({data})) } render() { return <Part {...this.state} {...this.props} /> } } } const ListWithGists = withData('https://api.github.com/users/gaearon/gists')(List)
In the above code, we use high-level components to extract the logic of api data acquisition. Next, we use react refetch to simplify the above asynchronous code
import { connect as refetchConnect } from 'react-refetch' const List = ({gists}) => { if (gists.pending) { return <div>loading...</div> } else if (gists.rejected) { return <div>{gists.reason}</div> } else if (gists.fulfilled) { return ( gists.fulfilled && <ul> {gists.value.map(gist => ( <li key={gist.id}>{gist.description}</li> ))} </ul> ) } } const ListWithGists = refetchConnect(() => ({gists: `https://api.github.com/users/gaearon/gists`}))(List)
In a moment, it's much more refreshing. By the way, using the properties provided by react refetch, the loading logic is also added
Separation of list and project responsibilities
Obviously, List component is a component of rendering List. Its duty is to render List. But we also deal with the logic of single Item here. We can separate the duty of List component from List component, while Gist only renders itself
const Gist = ({description}) => ( <li> {description} </li> ) const List = ({gists}) => { if (gists.pending) { return <div>loading...</div> } else if (gists.rejected) { return <div>{gists.reason}</div> } else if (gists.fulfilled) { return ( gists.fulfilled && <ul> {gists.value.map(gist => <Gist key={gist.id} {...gist} />)} </ul> ) } }
Use react refetch to add functionality to Gist
The connect method of react refetch receives a function as a parameter, which returns an object. If the value of the result object is a string, after obtaining the prop, a request will be made for the string. However, if the value is a function, it will not be executed immediately, but will be passed to the component for subsequent use
Value is string const connectWithStar = refetchConnect(() => ({gists: `https://api.github.com/users/gaearon/gists`})) //Value as function const connectWithStar = refetchConnect(({id}) => ({ star: () => ({ starResponse: { url: `https://api.github.com/gists/${id}/star?${token}`, method: 'PUT' } }) })) const Gist = ({description, star}) => ( <li> {description} <button onClick={star}>+1</button> </li> ) //After processing the Gist component, the star function will be passed to the prop of Gist, and then it can be used in Gist connectWithStar(Gist)