Files
flashmed-uploader/src/components/shared/fetches/fetcher.js
2026-08-08 18:53:36 +03:30

58 lines
1.7 KiB
JavaScript

import { useEffect } from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import Loader from '../loader';
import Error from '../error';
import { fetchData } from '../../utils/fetch';
import { ERROR, INIT, LOADING } from '../../../redux/constants';
function Fetcher(props) {
useEffect(() => fetchData(props.action), [props.action]);
// Loading
if ([INIT, LOADING].includes(props.status)) return <Loader />;
// Error
if (props.status === ERROR) {
const result = props.renderError(props.error);
if (result !== null) return result;
}
// Empty Data
if (
(Array.isArray(props.data) && props.data.length === 0) ||
(Object.entries(props.data).length === 0 && props.data.constructor === Object)
) {
const result = props.renderEmpty();
if (result !== null) return result;
}
// Good Condition
return props.children(props.data);
}
Fetcher.propTypes = {
action: PropTypes.func.isRequired,
stateSelector: PropTypes.func.isRequired,
status: PropTypes.string.isRequired,
data: PropTypes.oneOfType([PropTypes.object, PropTypes.arrayOf(PropTypes.object)]).isRequired,
renderEmpty: PropTypes.func.isRequired,
renderError: PropTypes.func.isRequired
};
Fetcher.defaultProps = {
renderEmpty: () => null,
renderError: () => <Error />
};
function mapStateToProps(state, { stateSelector }) {
return {
status: stateSelector(state).status,
error: stateSelector(state).error,
data: stateSelector(state).data
};
}
function mapDispatchToProps(dispatch, { action }) {
return bindActionCreators({ action }, dispatch);
}
export default connect(mapStateToProps, mapDispatchToProps)(Fetcher);