0
I have a problem of not knowing where to put the const "const [open, setOpen] = React.useState(false);" of a Modal from the Material UI, within my Generatereport class.
When I put " const [open, setOpen] = React.useState(false);" inside the render, the error " Error: Invalid hook call. Hooks can only be called Inside of the body of a Function Component".
My code is like this:
import React, { Component } from 'react';
//modal:
import Modal from '@material-ui/core/Modal';
import Backdrop from '@material-ui/core/Backdrop';
import Fade from '@material-ui/core/Fade';
import { connect } from 'react-redux';
import firebase from 'firebase/app';
import _ from 'lodash';
import { Link } from 'react-router-dom';
import { Form, Select, DatePicker, Popover } from 'antd';
import { LoadingOutlined, DownloadOutlined } from '@ant-design/icons';
import Button from '@material-ui/core/Button';
import { Container, ActionsForm, Loading } from './styles';
import ReactToExcel from 'react-html-table-to-excel';
import { changePage } from '../../../store/modules/user/actions';
import {
getAllEstablishmentsRequest,
getLocationsRequest,
} from '../../../store/modules/establishment/actions';
const { RangePicker } = DatePicker;
const configValidation = {
rules: [
{
type: 'array',
required: true,
message: 'Esse campo é obrigatório!',
},
],
};
const formRef = React.createRef();
// const rangeValue = fieldsValue['range-picker'];
class GenerateReport extends Component {
state = {
file: null,
update: false,
searchText: '',
searchedColumn: '',
establishment: [],
loading: false,
};
componentDidMount() {
this.setState({ loading: true });
// const { state } = this.props.location;
this.props.getLocationsRequest();
this.props.changePage(
'relatorio',
'GERADOR DE RELATÓRIOS',
'',
''
);
// this.props.getAllEstablishmentsRequest(this.props.profile)
firebase
.database()
.ref('/estabelecimentos_pedidos')
.once('value')
.then(snapshot => {
if (!this.props.profile.franqueado) {
this.setState({ establishment: _.values(snapshot.val()), loading: false });
} else {
const establishment = _.values(snapshot.val())
.map(usuario => {
if (usuario.email === this.props.profile.email) return;
if (usuario.localizacao === this.props.profile.localizacao) {
return usuario;
}
})
.filter(establishment => establishment !== undefined);
this.setState({ establishment, loading: false });
}
})
.catch(err => {
this.setState({ loading: false });
});
}
onFinish = async values => {
let localizacaoRef = '';
let fieldsValue = 0;
this.props.locations.map(location => {
if (location.nome === values.localizacao) {
localizacaoRef = location.uid;
}
});
this.props.getAllEstablishmentsRequest({
estabeReference: values.estabeReference,
nome: values.nome,
localizacao: values.localizacao,
localizacaoRef,
rangeValue: values.pedidos,
});
};
onChange = e => {
this.setState({ file: e.target.files[0] });
};
handleSearch = (selectedKeys, confirm, dataIndex) => {
confirm();
this.setState({
searchText: selectedKeys[0],
searchedColumn: dataIndex,
});
};
render() {
const {
loading,
locations,
loadingLocations,
loadingEstablishments,
establishments,
} = this.props;
const [open, setOpen] = React.useState(false);
//modal:
const handleOpen = () => {
setOpen(true);
};
const handleClose = () => {
setOpen(false);
};
return (
<Container>
<h1>Gerar Relatório Específico</h1>
<Form ref={formRef} onFinish={this.onFinish}>
<Popover
content={<strong>Período para o relatório</strong>}
placement="right"
trigger="hover"
>
<Form.Item name="range-picker" {...configValidation}>
<RangePicker
format="DD/MM/YYYY"
style={{ width: '100%' }}
/>
</Form.Item>
</Popover>
<Popover
content={<strong>Selecione a(s) Cidade(s)</strong>}
placement="right"
trigger="hover"
>
<Form.Item name="locations">
<Select
showSearch
mode="multiple"
optionFilterProp="children"
placeholder="Selecione a(s) Cidade(s)"
loading={loadingLocations}
filterOption={(input, option) =>
option.children.toLowerCase().indexOf(input.toLowerCase()) >=
0
}
>
<Select.Option value="" disabled>
Selecione a(s) Cidade(s)
</Select.Option>
{locations.map(location => (
<Select.Option
key={location.nome}
value={location.nome}
>
{location.nome}
</Select.Option>
))}
</Select>
</Form.Item>
</Popover>
<Popover
content={<strong>Selecione o(s) Estabelecimento(s)</strong>}
placement="right"
trigger="hover"
>
<Form.Item name="establishments">
<Select
showSearch
mode="multiple"
optionFilterProp="children"
placeholder="Selecione o(s) Estabelecimento(s)"
loading={loadingEstablishments}
filterOption={(input, option) =>
option.children.toLowerCase().indexOf(input.toLowerCase()) >=
0
}
>
<Select.Option value="" disabled>
Selecione o(s) Estabelecimento(s)
</Select.Option>
{establishments.map(establishment => (
<Select.Option
key={establishment.nome}
value={establishment.nome}
>
{establishment.nome}
</Select.Option>
))}
</Select>
</Form.Item>
</Popover>
{loading ? (
<Loading>
<LoadingOutlined />
</Loading>
) : (
<Form.Item>
<ActionsForm>
<button type="button" onClick={handleOpen}>
react-transition-group
</button>
<Modal
aria-labelledby="transition-modal-title"
aria-describedby="transition-modal-description"
// className={classes.modal}
open={open}
onClose={handleClose}
closeAfterTransition
BackdropComponent={Backdrop}
BackdropProps={{
timeout: 500,
}}
>
<Fade in={open}>
<div
// className={classes.paper}
>
<h2 id="transition-modal-title">Transition modal</h2>
<p id="transition-modal-description">react-transition-group animates me.</p>
</div>
</Fade>
</Modal>
<Button
type="submit"
disabled={loading}
onClick={(_handleOpenTable) => window.open("", "_self")}
>
Gerar
</Button>
{/* <button type="button" onClick={{}}>
Open Modal</button> */}
<ReactToExcel
table="table-to-xls"
filename={`Relatório-QPreço`}
sheet="Tabela 1"
buttonText="Exportar para Excel"
>
Teste
</ ReactToExcel>
<Link to="/reports">
Voltar para Relatórios
</Link>
</ActionsForm>
</Form.Item>
)}
</Form>
<table id="table-to-xls">
</table>
</Container>
);
}
}
const mapStateToProps = state => ({
loading: state.establishment.loading,
locations: state.establishment.locations,
loadingEstablishments: state.establishment.loading,
establishments: state.establishment.establishments,
});
const mapDispatchToProps = {
changePage,
getLocationsRequest,
getAllEstablishmentsRequest,
};
export default connect(mapStateToProps, mapDispatchToProps)(GenerateReport);
You cannot use the Hooks within a class component, as you say in the error you can only use Hooks within a functional component. I believe you can include this information within your
state
.– Gabriel José de Oliveira