diff --git a/README.md b/README.md
index 2781e0c..49f34ab 100644
--- a/README.md
+++ b/README.md
@@ -36,26 +36,24 @@ $ npm install react-loads
```js
import React from 'react';
-import Loads, { IfIdle, IfLoading, IfTimeout, IfSuccess, IfError } from 'react-loads';
+import Loads from 'react-loads';
const getRandomDog = () => axios.get('https://dog.ceo/api/breeds/image/random');
export default () => (
- {({ load, response, error }) => (
+ {({ isIdle, isLoading, isSuccess, load, response, state, error }) => (
-
- Load random dog
-
-
loading...
-
taking a while...
-
- {response && }
+ {isIdle && Load random dog }
+ {isLoading && loading...
}
+ {isSuccess && (
-
Load another dog
+ {response &&
}
+
+ Load another dog
+
-
-
Error! {error}
+ )}
)}
@@ -76,7 +74,7 @@ export default () => (
Prop Type Default value Description
- children ({ response?: any, error?: any, load: (...args: any) => ?Promise<any>, reset: Function, state: 'idle' | 'loading' | 'timeout' | 'success' | 'error' })
N/A (required)
+ children ({ response?: any, error?: any, load: (...args: any) => ?Promise<any>, resetState: Function })
N/A (required)
delay number
300
Number of milliseconds before component transitions to loading
state upon invoking fn
/load
.
loadOnMount boolean
false
Whether or not to invoke the fn
on mount.
fn (...args: any) => Promise<any>
N/A (required) The promise to invoke.
@@ -92,60 +90,15 @@ export default () => (
response any
Response from the resolved promise (`fn`)
error any
Error from the rejected promise (`fn`)
load (...args: any) => ?Promise<any>
Trigger to load `fn`
+ isIdle boolean
Returns `true` if the state is idle (`fn` has not been triggered).
+ isLoading boolean
Returns `true` if the state is loading (`fn` is in a pending state).
+ isTimeout boolean
Returns `true` if the state is timeout (`fn` is in a pending state for longer than `delay` milliseconds).
+ isSuccess boolean
Returns `true` if the state is success (`fn` has been resolved).
+ isError boolean
Returns `true` if the state is error (`fn` has been rejected).
resetState () => void
Reset state back to `idle`.
- state 'idle' | 'loading' | 'timeout' | 'success' | 'error'
Current state.
-### ``, ``, ``, ``, ``
-
-These components determine what node to render based on the loading/response state.
-
-#### Definitions
-
-- `IfIdle` - Will render when the state is 'idle' (the initial state).
-- `IfLoading` - Will render when the state is 'loading' (triggered when the promise (`fn`) is pending).
-- `IfTimeout` - Will render when the state is 'timeout' (triggered when the promise (`fn`) has not resolved/rejected after a period of time).
-- `IfSuccess` - Will render when the state is 'success' (triggered when the promise (`fn`) resolves).
-- `IfError` - Will render when the state is 'error' (triggered when the promise (`fn`) rejects).
-
-#### Props
-
-
-Prop Type Default value Description
-
- channel string null
The key of the context from where to read the state.
- children node N/A (required) The children to be rendered when the
- conditions match.
- onShow func The function invoked when the component becomes visible.
- onHide func The function invoked when the component becomes hidden.
-
-
-
-### ``
-
-A component to define which parts of the tree should be rendered for a set of states.
-
-#### Props
-
-
-Prop Type Default value Description
-
- is oneOfType(arrayOf(string), string) N/A (required) The states(s) for which the children should be shown. Available states: 'idle'
, 'loading'
, 'timeout'
, 'success'
, 'error'
- channel string null
The key of the context from where to read the state.
- children node N/A (required) The children to be rendered when the
- conditions match.
- onShow func The function invoked when the component becomes visible.
- onHide func The function invoked when the component becomes hidden.
-
-
-
-```jsx
-
- Hello world!
-
-```
-
## Special thanks
- [Michele Bertoli](https://github.com/MicheleBertoli) for creating [React Automata](https://github.com/MicheleBertoli/react-automata) - it's awesome and you should check it out.
diff --git a/package.json b/package.json
index b595a36..2838b3d 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "react-loads",
- "version": "3.1.0",
+ "version": "4.0.0-canary.1",
"description": "A simple React component to handle loading state",
"license": "MIT",
"repository": "jxom/react-loads",
diff --git a/src/__stories__/index.stories.js b/src/__stories__/index.stories.js
index 3036c39..49f4ba8 100644
--- a/src/__stories__/index.stories.js
+++ b/src/__stories__/index.stories.js
@@ -3,27 +3,26 @@
import React, { Fragment } from 'react';
import { storiesOf } from '@storybook/react';
import axios from 'axios';
-import Loads, { IfState, IfIdle, IfLoading, IfSuccess, IfTimeout, IfError } from '../index';
+import Loads from '../index';
storiesOf('Loads', module)
.add('default usage', () => {
const getRandomDog = () => axios.get('https://dog.ceo/api/breeds/image/random');
return (
- {({ load, response, state, error }) => (
+ {({ isIdle, isLoading, isSuccess, load, response, state, error }) => (
Current state: {state}
-
- Load random dog
-
-
loading...
-
- {response && }
+ {isIdle && Load random dog }
+ {isLoading && loading...
}
+ {isSuccess && (
-
Load another dog
+ {response &&
}
+
+ Load another dog
+
-
-
Error! {error}
+ )}
)}
@@ -33,20 +32,19 @@ storiesOf('Loads', module)
const getRandomDog = () => axios.get('https://dog.ceo/api/breeds/image/random');
return (
- {({ load, response, state, error }) => (
+ {({ isIdle, isLoading, isSuccess, load, response, state, error }) => (
Current state: {state}
-
- Load random dog
-
-
loading...
-
- {response && }
+ {isIdle && Load random dog }
+ {isLoading && loading...
}
+ {isSuccess && (
-
Load another dog
+ {response &&
}
+
+ Load another dog
+
-
-
Error! {error}
+ )}
)}
@@ -56,20 +54,19 @@ storiesOf('Loads', module)
const getRandomDog = () => axios.get('https://dog.ceo/api/breeds/image/random');
return (
- {({ load, response, state, error }) => (
+ {({ isIdle, isLoading, isSuccess, load, response, state, error }) => (
Current state: {state}
-
- Load random dog
-
- loading...
-
- {response && }
+ {isIdle && Load random dog }
+ {isLoading && loading...
}
+ {isSuccess && (
-
Load another dog
+ {response &&
}
+
+ Load another dog
+
-
- Error! {error}
+ )}
)}
@@ -79,20 +76,19 @@ storiesOf('Loads', module)
const getRandomDog = () => axios.get('https://dog.ceo/api/breeds/image/random');
return (
- {({ load, response, state, error }) => (
+ {({ isIdle, isLoading, isSuccess, load, response, state, error }) => (
Current state: {state}
-
- Load random dog
-
- loading...
-
- {response && }
+ {isIdle && Load random dog }
+ {isLoading && loading...
}
+ {isSuccess && (
-
Load another dog
+ {response &&
}
+
+ Load another dog
+
-
- Error! {error}
+ )}
)}
@@ -104,20 +100,20 @@ storiesOf('Loads', module)
};
return (
- {({ load, response, state, error }) => (
+ {({ isIdle, isLoading, isSuccess, isError, load, response, state, error }) => (
Current state: {state}
-
- Load random dog
-
- loading...
-
- {response && }
+ {isIdle && Load random dog }
+ {isLoading && loading...
}
+ {isSuccess && (
-
Load another dog
+ {response &&
}
+
+ Load another dog
+
-
- Error! {error && error.message}
+ )}
+ {isError && Error! {error}
}
)}
@@ -128,21 +124,20 @@ storiesOf('Loads', module)
new Promise(resolve => setTimeout(() => resolve(axios.get('https://dog.ceo/api/breeds/image/random')), 3000));
return (
- {({ load, response, state, error }) => (
+ {({ isIdle, isLoading, isSuccess, isTimeout, load, response, state, error }) => (
Current state: {state}
-
- Load random dog
-
- loading...
- taking a while...
-
- {response && }
+ {isIdle && Load random dog }
+ {isLoading && loading...
}
+ {isTimeout && taking a while...
}
+ {isSuccess && (
-
Load another dog
+ {response &&
}
+
+ Load another dog
+
-
- Error! {error && error.message}
+ )}
)}
@@ -152,20 +147,19 @@ storiesOf('Loads', module)
const getRandomDogByBreed = breed => axios.get(`https://dog.ceo/api/breed/${breed}/images/random`);
return (
- {({ load, response, state, error }) => (
+ {({ isIdle, isLoading, isSuccess, load, response, state, error }) => (
Current state: {state}
-
- load('beagle')}>Load random beagle
-
-
loading...
-
- {response && }
+ {isIdle && load('beagle')}>Load random beagle }
+ {isLoading && loading...
}
+ {isSuccess && (
-
load('beagle')}>Load another beagle
+ {response &&
}
+
+ load('beagle')}>Load another beagle
+
-
-
Error! {error}
+ )}
)}
@@ -175,26 +169,40 @@ storiesOf('Loads', module)
const getRandomDog = () => axios.get(`https://dog.ceo/api/breeds/image/random`);
const saveDog = randomDogResponse => new Promise(resolve => setTimeout(() => resolve(randomDogResponse), 1000));
return (
-
- {({ load: loadRandomDog, response: randomDogResponse, error: randomDogError }) => (
-
- {({ load: saveDog, state: saveDogState }) => (
+
+ {({
+ isIdle: isRandomDogIdle,
+ isLoading: isRandomDogLoading,
+ isError: isRandomDogError,
+ isSuccess: isRandomDogSuccess,
+ load: loadRandomDog,
+ response: randomDogResponse,
+ error: randomDogError
+ }) => (
+
+ {({
+ isLoading: isSaveDogLoading,
+ isSuccess: isSaveDogSuccess,
+ isIdle: isSaveDogIdle,
+ load: saveDog,
+ state: saveDogState
+ }) => (
-
- Load random dog
-
-
loading...
-
- {randomDogResponse && }
+ {isRandomDogIdle && Load random dog }
+ {isRandomDogLoading && loading...
}
+ {isRandomDogSuccess && (
-
saving...
-
saved dog!
-
- saveDog(randomDogResponse)}>Save dog
-
+ {randomDogResponse &&
}
+
+ {isSaveDogLoading &&
saving...
}
+ {isSaveDogSuccess &&
saved dog!
}
+ {(isSaveDogSuccess || isSaveDogIdle) && (
+
saveDog(randomDogResponse)}>Save dog
+ )}
+
-
-
Error! {randomDogError}
+ )}
+ {isRandomDogError &&
Error! {randomDogError}
}
)}
diff --git a/src/index.js b/src/index.js
index 1e53870..7ced9f1 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,8 +1,7 @@
// @flow
-import { createElement, Component } from 'react';
+import { Component } from 'react';
import { withStatechart } from 'react-automata';
-export * from './states';
const statechart = {
initial: 'idle',
@@ -49,10 +48,15 @@ const statechart = {
type Props = {
children: ({
- response?: any,
- error?: any,
- load?: (...args: any) => ?Promise,
+ error: any,
+ isError: boolean,
+ isIdle: boolean,
+ isLoading: boolean,
+ isSuccess: boolean,
+ isTimeout: boolean,
+ load: (...args: any) => ?Promise,
resetState: () => void,
+ response: any,
state: string
}) => any,
delay?: number,
@@ -157,6 +161,11 @@ class Loads extends Component {
const state = machineState.value;
return children({
error,
+ isIdle: state === 'idle',
+ isLoading: state === 'loading',
+ isTimeout: state === 'timeout',
+ isSuccess: state === 'success',
+ isError: state === 'error',
load: this.handleLoad,
resetState: () => this.transition('RESET'),
response,
@@ -165,9 +174,4 @@ class Loads extends Component {
};
}
-const _default = ({ channel, ...props }: { channel?: ?string }) =>
- createElement(withStatechart(statechart, { channel })(Loads), props);
-
-_default.defaultProps = { channel: null };
-
-export default _default;
+export default withStatechart(statechart)(Loads);
diff --git a/src/states.js b/src/states.js
deleted file mode 100644
index 9088c53..0000000
--- a/src/states.js
+++ /dev/null
@@ -1,20 +0,0 @@
-// @flow
-import React, { type Node } from 'react';
-import { State as AutomataState } from 'react-automata';
-
-type State = 'success' | 'error' | 'timeout' | 'loading' | 'idle';
-type StateProps = {
- channel?: string,
- children: Node
-};
-
-export const IfState = ({ channel, children, is, ...props }: { ...StateProps, is: Array | State }) => (
-
- {children}
-
-);
-export const IfIdle = (props: StateProps) => IfState({ is: 'idle', ...props });
-export const IfLoading = (props: StateProps) => IfState({ is: 'loading', ...props });
-export const IfTimeout = (props: StateProps) => IfState({ is: 'timeout', ...props });
-export const IfSuccess = (props: StateProps) => IfState({ is: 'success', ...props });
-export const IfError = (props: StateProps) => IfState({ is: 'error', ...props });