You have to add your initial configurations and then you just ask what you need from the data store.
This library fetch and stores your data on reducers normalized, keeping your data updated & consistent, avoiding duplicate entities.
You can always add custom logic on reducers or on saga middleware.
npm i --save redux-relax-saga
npm i --save redux-relax-thunk
import { createStore } from 'redux';
import DevTools from '../containers/DevTools';
import rootReducer from '../reducers';
import ReduxRelaxEnchancer from 'redux-relax-thunk';
const configs = {
dev: true,
apiEndpoint: 'https://api.github.com/',//required
getHeaders: (state) => ({ }),
reducers: {
paginate: {
totalPageCountField: 'pages', //required
totalCountField: 'totalCount', //required
currentPageField: undefined //optional
},
},
entities: [
{
uniqueIdAttribute: 'login', // The field that is used as unique id - Required
name: 'users', // Name of the entities field in state- Required
itemsField: 'items', // the field on response payload that includes our data
singleApiUrl: login => `users/${login.toString()}` // The route to base endpoint to fetch a single entity - Required,
apiUrl: login => `repos/${login}/stargazers`, // The route to base endpoint to fetch multiple entities - Required,
paginationKey: 'login',
}, {
uniqueIdAttribute: 'fullName',
name: 'repos',
itemsField: 'items',
singleApiUrl: fullName => `repos/${fullName}`,
apiUrl: login => `users/${login}/starred`,
paginationKey: 'fullName',
},
]
}
const store = createStore(
rootReducer,
{},
ReduxRelaxEnchancer(configs, [DevTools.instrument()]),
);
export default store
@multiple('repos', (state, ownProps) => {
const { login } = state.router.params; //The pagination key to get all repos for user with username = {login}
return { search: login};
})
@single('users', (state, ownProps) => {
const { login } = state.router.params; //The entities key to get user with id = {login}
return login;
})
class UserPage extends Component {
componentWillReceiveProps(nextProps) {
if (this.props.login !== nextProps.login) {
this.props.loadUser(nextProps.login) //You also have loadUser as prop since you asked for @single - users
this.props.loadRepos(nextProps.login) //You also have loadRepos as prop since you asked for @multiple - repos
}
}
handleLoadMoreClick() {
this.props.loadMoreRepos(this.props.login) // You also have loadMoreRepos as prop since you asked for multiple - repos
}
render() {
...
}
};
function mapStateToProps(state) {
const { login } = state.router.params
const {
entities: { users, repos }
} = state
return {
login,
user: users[login]
}
}
export default connect(mapStateToProps, {
})(UserPage)
class UserPage extends Component {
componentWillReceiveProps(nextProps) {
if (this.props.login !== nextProps.login) {
this.props.loadUser(nextProps.login) // You also have loadUser as prop since you asked for single - users
this.props.loadRepos(nextProps.login) // You also have loadRepos as prop since you asked for multiple - repos
}
}
handleLoadMoreClick() {
this.props.loadMoreRepos(this.props.login) // You also have loadMoreRepos as prop since you asked for multiple - repos
}
render() {
...
}
};
UserPage = multiple('repos', (state, ownProps) => {
const { login } = state.router.params; //The pagination key to get all repos for user with username = {login}
return { search: login };
})(UserPage);
UserPage = single('users', (state, ownProps) => {
const { login } = state.router.params; //The entities key to get user with id = {login}
return login;
})(UserPage)
function mapStateToProps(state) {
const { login } = state.router.params
const {
entities: { users, repos }
} = state
return {
login,
user: users[login]
}
}
export default connect(mapStateToProps, {
})(UserPage)