Skip to content

Commit

Permalink
Changing withAxios HoC prop onReload to be more generic `makeReques…
Browse files Browse the repository at this point in the history
…t` which also matches the `Request` component composition.
  • Loading branch information
sheaivey committed Nov 23, 2018
1 parent f1ed8d0 commit 71ae28f
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 33 deletions.
18 changes: 9 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ This is intended to allow in render async requests.

- Same great features found in [Axios](https://github.com/mzabriskie/axios)
- Component driven
- Child function callback ***(error, response, isLoading, onReload, axios) => { }***
- Child function callback ***(error, response, isLoading, makeRequest, axios) => { }***
- Auto cancel previous requests
- Debounce to prevent rapid calls.
- Request only invoked on prop change and *isReady* state.
- Callback props for ***onSuccess***, ***onError***, and ***onLoading***
- Supports custom axios instances through ***props*** or a ***<AxiosProvider ... >***
- Create your own request components wrapped using the withAxios({options})(ComponentToBeWrapped) HoC
- Create your own request components wrapped using the ***withAxios({options})(ComponentToBeWrapped)*** HoC

## Installing

Expand Down Expand Up @@ -81,15 +81,15 @@ render() {
return (
<div>
<Get url="/api/user" params={{id: "12345"}}>
{(error, response, isLoading, onReload, axios) => {
{(error, response, isLoading, makeRequest, axios) => {
if(error) {
return (<div>Something bad happened: {error.message} <button onClick={() => onReload({ params: { reload: true } })}>Retry</button></div>)
return (<div>Something bad happened: {error.message} <button onClick={() => makeRequest({ params: { reload: true } })}>Retry</button></div>)
}
else if(isLoading) {
return (<div>Loading...</div>)
}
else if(response !== null) {
return (<div>{response.data.message} <button onClick={() => onReload({ params: { refresh: true } })}>Refresh</button></div>)
return (<div>{response.data.message} <button onClick={() => makeRequest({ params: { refresh: true } })}>Refresh</button></div>)
}
return (<div>Default message before request is made.</div>)
}}
Expand All @@ -106,7 +106,7 @@ render() {

`isLoading` Boolean flag indicating if Axios is currently making a XHR request.

`onReload(props)` Function to invoke another XHR request. This function accepts new temporary props that will be overloaded with the existing props for this request only.
`makeRequest(props)` Function to invoke another XHR request. This function accepts new temporary props that will be overloaded with the existing props for this request only.

`axios` current instance of axios being used.

Expand All @@ -127,7 +127,7 @@ Pass down through a provider
```jsx
<AxiosProvider instance={axiosInstance}>
<Get url="test">
{(error, response, isLoading, onReload, axios) => {
{(error, response, isLoading, makeRequest, axios) => {
...
}}
</Get>
Expand All @@ -137,7 +137,7 @@ Pass down through a provider
Or pass down through props
```jsx
<Get url="test" instance={axiosInstance}>
{(error, response, isLoading, onReload, axios) => {
{(error, response, isLoading, makeRequest, axios) => {
...
}}
</Get>
Expand Down Expand Up @@ -176,7 +176,7 @@ const MyComponent = withAxios({
params: {id: "12345"}
})(class MyComponentRaw extends React.Component {
render() {
const {error, response, isLoading, onReload, axios} = this.props
const {error, response, isLoading, makeRequest, axios} = this.props
if(error) {
return (<div>Something bad happened: {error.message}</div>)
} else if(isLoading) {
Expand Down
4 changes: 3 additions & 1 deletion __tests__/utils.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,9 @@ describe('components', () => {
expect(props.error).toBe(null)
expect(props.response).toBe(null)
expect(props.isLoading).toBe(false)
expect(typeof props.onReload).toBe('function')
expect(typeof props.makeRequest).toBe('function')
expect(typeof props.axios).toBe('function')
expect(typeof props.options).toBe('object')
})
})
})
6 changes: 3 additions & 3 deletions examples/advanced/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,14 @@ class App extends React.Component {
onLoading={()=>this.setState({ isLoading: true })}
onError={()=>this.setState({ isReady: false, isLoading: false })}
>
{(error, response, isLoading, onReload) => {
{(error, response, isLoading, makeRequest) => {
if(error) {
console.log(response)
return (<div>Something bad happened: {error.message} <button className="info" onClick={() => onReload()}>Retry</button></div>)
return (<div>Something bad happened: {error.message} <button className="info" onClick={() => makeRequest()}>Retry</button></div>)
} else if(isLoading) {
return (<div className="loader"></div>)
} else if(response !== null) {
return (<div>{response.data.message} <button className="info" onClick={() => onReload({ params:{ refresh: true } })}>Refresh</button></div>)
return (<div>{response.data.message} <button className="info" onClick={() => makeRequest({ params:{ refresh: true } })}>Refresh</button></div>)
}
return <div>Click a button to test its action.</div>
}}
Expand Down
6 changes: 5 additions & 1 deletion examples/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,14 @@ let WebpackConfig = require('./webpack.config')

let app = express()

app.all('/api/*', (req, res) => { // Fake API response
app.all('/api/*', (req, res) => { // Fake API response with timeout
setTimeout(() => { res.status(200).json({ message: 'Success! ' + req.method + ' ' + req.url }) }, 1000)
})

app.all('/error*', (req, res) => { // Fake ERROR response with timeout
setTimeout(() => { res.status(404).json({ message: 'Error 404! ' + req.method + ' ' + req.url }) }, 500)
})

app.use(webpackDevMiddleware(webpack(WebpackConfig), {
publicPath: '/__build__/',
stats: {
Expand Down
5 changes: 4 additions & 1 deletion examples/withAxios/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ class App extends React.Component {
<h2>Overloading withAxios HoC config options</h2>
<DemoComponentHoC options={{ method: 'post', url: '/api/overloaded' }} />

<h2>Overloading url=undefined withAxios HoC config options</h2>
<DemoComponentHoC options={{ method: 'post', url: undefined }} />

<h2>Children withAxios HoC</h2>
<DemoComponentHoC><div className="success">children</div></DemoComponentHoC>
</code>
Expand All @@ -26,7 +29,7 @@ class App extends React.Component {
/* eslint react/prop-types: 0 */
class DemoComponent extends React.Component {
render() {
const { error, response, isLoading, children, customProp, onRendered } = this.props
const { error, response, isLoading, children, customProp, axios, makeRequest } = this.props
if(error) {
return (<div>Something bad happened: {error.message}</div>)
} else if(isLoading) {
Expand Down
30 changes: 14 additions & 16 deletions src/components/Request.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,19 @@ class Request extends React.Component {
let oldPropStr = JSON.stringify(this.props)
let newPropStr = JSON.stringify(newProps)
if (oldPropStr != newPropStr && newProps.isReady) {
this.debounceMakeRequest(this.getConfig(newProps))
this.debounceMakeRequest(newProps, this.getConfig(newProps))
}
}

componentDidMount() {
this._mounted = true
if (this.props.isReady) {
this.debounceMakeRequest(this.getConfig(this.props))
this.debounceMakeRequest(this.props, this.getConfig(this.props))
}
}

onReload(props) {
if (!this.state.isLoading) {
this.debounceMakeRequest(this.getConfig(props ? Object.assign({}, this.props, props) : this.props))
}
onMakeReload(props) {
this.debounceMakeRequest(props || this.props, this.getConfig(props ? Object.assign({}, this.props, props) : this.props))
}

componentWillUnmount() {
Expand All @@ -56,9 +54,9 @@ class Request extends React.Component {
return Object.assign({ url: props.url, method: props.method, data: props.data, params: props.params }, props.config)
}

makeRequest(config) {
const _axios = this.props.instance || this.context.axios || axios
if (!this._mounted || !this.props.isReady || this.props.url === undefined) {
makeRequest(props, config) {
const _axios = props.instance || this.context.axios || axios
if (!this._mounted || config.url === undefined) {
return
}
// setup cancel tokens
Expand All @@ -69,8 +67,8 @@ class Request extends React.Component {

// set the isLoading flag
this.setState({ isLoading: true, error: null })
if (typeof this.props.onLoading === 'function') {
this.props.onLoading()
if (typeof props.onLoading === 'function') {
props.onLoading()
}

// time to make the axios request
Expand All @@ -79,17 +77,17 @@ class Request extends React.Component {
return
}
this.setState({ isLoading: false, response: res })
if (typeof this.props.onSuccess === 'function') {
this.props.onSuccess(res)
if (typeof props.onSuccess === 'function') {
props.onSuccess(res)
}
}, (err) => {
if (!this._mounted) {
return
}
if (!axios.isCancel(err)) {
this.setState({ isLoading: false, response: err.response, error: err })
if (typeof this.props.onError === 'function') {
this.props.onError(err)
if (typeof props.onError === 'function') {
props.onError(err)
}
}
})
Expand All @@ -102,7 +100,7 @@ class Request extends React.Component {
this.state.error,
this.state.response,
this.state.isLoading,
(props) => this.onReload(props),
(props) => this.onMakeReload(props),
_axios
)
}
Expand Down
4 changes: 2 additions & 2 deletions src/components/withAxios.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,13 @@ export const withAxios = (mixed = {}) => {
const newOptions = { ...options, ...this.props.options }
return (
<Request {...newOptions}>
{(error, response, isLoading, onReload, axios) => (
{(error, response, isLoading, makeRequest, axios) => (
<WrappedComponent
{...this.props}
error={error}
response={response}
isLoading={isLoading}
onReload={onReload}
makeRequest={makeRequest}
axios={axios}
options={newOptions}
/>
Expand Down

0 comments on commit 71ae28f

Please sign in to comment.