Hello guys so i tried to make global state so the other page can use the state. The problem is i got an error that says:
Login.js:18 Uncaught TypeError: Cannot destructure property 'emailLog' of '(0 , react__WEBPACK_IMPORTED_MODULE_0__.useContext)(...)' as it is undefined.
Im doing this because i want the email from user after logged in and pass them to another page so that i can display the logged in user.
App.js:
export const EmailUser = React.createContext();
function App() {
Axios.defaults.withCredentials = true;
const [invoice, setInvoice] = useState("");
const [currency, setCurrency] = useState("IDR");
const [myFile, setMyFile] = useState("");
const [emailLog, setEmailLog] = useState("");
return (
<EmailUser.Provider value={{ emailLog, setEmailLog }}>
<div className="App">
<BasicExample />
<div className="formInput">
<form method="POST" encType="multipart/form-data" action="http://localhost:3001/upload">
<div className="textUser"></div>
<input
className="inputForm"
defaultValue={emailLog}
type="email"
disabled
name="email"
/>
<input className="inputForm" type="number" placeholder="Invoice No" name="InvoiceNo" />
<input className="inputForm" type="date" name="Invoice_Date" />
<input className="inputForm" type="text" placeholder="Description" name="Description" />
<select
className="selectBox"
name="Currency"
onChange={(e) => {
setCurrency(e.target.value);
}}
>
<option value="IDR">IDR</option>
<option value="USD">USD</option>
<option value="YEN">YEN</option>
</select>
<input className="inputForm" type="number" placeholder="Amount" name="Amount" />
<input
className="custom-file-upload"
multiple
type="file"
name="DocumentFile"
onChange={(e) => {
setMyFile(e.target.value);
}}
/>
<button className="btnSubmit">Submit</button>
</form>
</div>
</div>
</EmailUser.Provider>
);
}
export default App;
Login.js
const Login = () => {
let navigate = useNavigate();
const { emailLog, setEmailLog } = useContext(EmailUser);
const [passwordLog, setPasswordLog] = useState("");
const [loginStatus, setLoginStatus] = useState("");
Axios.defaults.withCredentials = true;
const login = (e) => {
e.preventDefault();
Axios.post("http://localhost:3001/login", {
email: emailLog,
password: passwordLog,
}).then((response) => {
console.log(response);
if (response.data.message) {
alert(response.data.message);
} else {
setLoginStatus(response.data[0].email);
alert("Redirecting");
navigate("/home");
}
});
};
console.log(emailLog);
useEffect(() => {
Axios.get("http://localhost:3001/login").then((response) => {
if (response.data.loggedIn == true) {
setLoginStatus(response.data.email[0].email);
}
});
});
return (
<div>
<img className="wave" src={Wave} />
<img className="wave2" src={WaveV2} />
<div className="wrapper">
<div className="img">{/* <img src={Background}/> */}</div>
<div className="register-content">
<div className="registerForm">
<img src={Avatar} />
<h2 className="title">Welcome</h2>
<div className="input-div one">
<div className="i">
<i className="fas fa-user">
<GrMail />
</i>
</div>
<div className="div">
<input
type="email"
className="input"
placeholder="Email"
required
onChange={(e) => {
setEmailLog(e.target.value);
}}
/>
</div>
</div>
<div className="input-div pass">
<div className="i">
<i className="fas fa-lock">
<AiFillLock />
</i>
</div>
<div className="div">
<input
type="password"
className="input"
placeholder="Password"
required
onChange={(e) => {
setPasswordLog(e.target.value);
}}
/>
</div>
</div>
Don't have an account ?
<button type="submit" className="btn" onClick={login}>
Login
</button>
</div>
</div>
</div>
</div>
);
};
export default Login;
EmailUser context works only with the components that are children of EmailUser.Provider, and it doesn't seem to be the case for Login component. An easy way is to create a separate component, in some EmailUserProvider.js, like so:
import {createContext, useState} from "react"
export const EmailUser = createContext();
export default function EmailUserProvider({children}) {
const [emailLog, setEmailLog] = useState("");
return (
<EmailUser.Provider value={{ emailLog, setEmailLog }}>
{children}
</EmailUser.Provider>
);
}
And make it wrap all the components that would consume it. If I assume all my components and routes are rendered in App and want the context to be global, I would do so:
<EmailUserProvider>
<App/>
</EmailUserProvider>
There are two components
WelcomePage.jsx
import { useState } from "react";
import SignUpPage from "./SignUpPage";
function WelcomePage() {
const [signUp, toSignUp] = useState(false);
function signUpClick() {
toSignUp(true);
}
return (
<div>
{signUp ? (
<SignUpPage isOpen={signUp} />
) : (
<div
className="Welcome_page__container animate__animated animate__fadeIn"
id="welcome_page"
>
<h1 className="Welcome_page__title">Welcome to Hotel Review </h1>
<h3 className="Welcome_page__subtitle">Sign in :</h3>
<div className="Welcome_page__wrapper">
<label className="Welcome_page__input-title" htmlFor="welcome_mail">
E-mail:
</label>
<input
className="Welcome_page__input"
id="welcome_mail"
type="mail"
placeholder="Your e-mail..."
/>
<label className="Welcome_page__input-title" htmlFor="welcome_pass">
Password:
</label>
<input
className="Welcome_page__input"
id="welcome_pass"
type="text"
placeholder="Your password..."
/>
<button className="Welcome_page__btn">Login</button>
<button className="Welcome_page__btn" onClick={signUpClick}>
Sign Up
</button>
</div>
</div>
)}
</div>
);
}
export default WelcomePage;
SignUpPage.jsx
function SignUpPage() {
return (
<div className="Welcome_page__container animate__animated animate__fadeIn">
<button>Back...</button>
<h1 className="Welcome_page__title">Welcome to Hotel Review </h1>
<h3 className="Welcome_page__subtitle">Sign up :</h3>
<div className="Welcome_page__wrapper">
<label className="Welcome_page__input-title" htmlFor="welcome_mail">
E-mail:
</label>
<input
className="Welcome_page__input"
id="welcome_mail"
type="mail"
placeholder="Your e-mail..."
/>
<label className="Welcome_page__input-title" htmlFor="welcome_pass">
Password:
</label>
<input
className="Welcome_page__input"
id="welcome_pass"
type="text"
placeholder="Your password..."
/>
<label
className="Welcome_page__input-title"
htmlFor="welcome_pass"
></label>
<input
className="Welcome_page__input"
id="welcome_pass_repeat"
type="text"
placeholder="Repeat password..."
/>
<button className="Welcome_page__btn_2">Sign Up</button>
</div>
</div>
);
}
export default SignUpPage;
Clicking the "Sign Up" button in WelcomePage.jsx using useState navigates to SignUpPage.jsx
Question - How can I return back to WelcomePage.jsx on the "Back" button (I understand that I need to return false back to const [signUp, toSignUp] = useState() , but I don't know how to transfer state from WelcomePage to SignUpPage and vice versa.)
You can pass it via props from parent to child component.
And pass the setState from child component to parent.
import { useState } from "react";
import SignUpPage from "./SignUpPage";
function WelcomePage() {
const [signUp, setSignUp] = useState(false);
function signUpClick() {
toSignUp(true);
}
return (
<>
{signUp ? (
<SignUpPage isOpen={signUp} setOpen={setSignUp} />
) : (
<div>
... component
</div>
)
</>
);
}
export default WelcomePage;
function SignUpPage(props) {
const { isOpen, setOpen } = props;
return (
<>
{isOpen}
<button onClick={setOpen(true)}>Open</button>
<button onClick={setOpen(false)}>Close</button>
</>
);
}
export default SignUpPage;
I am building a login and register app using react and on inspec after hitting Sing up I get the error:
Cannot POST /localhost:8000/register
On the console, the following message is displayed:
POST http://localhost:3001/localhost:8000/register 404 (Not Found)
My app.js looks like this:
import 'bootstrap/dist/css/bootstrap.min.css';
import React from 'react';
import { BrowserRouter,Switch,Route } from "react-router-dom";
import './App.css';
import Home from './components/home_component';
import Nav from './components/nav_component';
import Login from './components/login_component';
import Register from './components/register_component';
function App() {
return (
<BrowserRouter>
<div className="App">
<Nav/>
<div className="auth-wrapper">
<div className="auth-inner">
<Switch>
<Route exact path="/" component={Home}/>
<Route exact path="/login" component={Login}/>
<Route exact path="/register" component={Register}/>
</Switch>
</div>
</div>
</div>
</BrowserRouter>
);
}
export default App;
my register_component.js looks like this:
import React, { Component } from 'react';
import axios from 'axios';
class Register extends Component {
handleSubmit = e => {
e.preventDefault();
const data = {
first_name: this.firstName,
last_name: this.lastName,
email: this.email,
password: this.password,
password_confirm: this.confirmPassword
};
axios.post('http:/localhost:8000/register', data).then(
res =>{
console.log(res);
}
).catch(err =>{
console.log(err);
})
};
render() {
return (
<form onSubmit={this.handleSubmit}>
<h3>Sign Up</h3>
<div className="form-group">
<label>First Name</label>
<input type='text' className='form-control' placeholder='First Name' onChange={e => this.firstName = e.target.value}/>
</div>
<div className="form-group">
<label>Last Name</label>
<input type='text' className='form-control' placeholder='Last Name' onChange={e => this.lastName = e.target.value}/>
</div>
<div className="form-group">
<label>Email</label>
<input type='email' className='form-control' placeholder='Email' onChange={e => this.email = e.target.value}/>
</div>
<div className="form-group">
<label>Password</label>
<input type='password' className='form-control' placeholder='Password'onChange={e => this.password = e.target.value}/>
</div>
<div className="form-group">
<label>Confirm Password</label>
<input type='password' className='form-control' placeholder=' Confirm Password' onChange={e => this.confirmPassword = e.target.value}/>
</div>
<button className='btn btn-primary btn-block'>Sign Up</button>
</form>
);
}
}
export default Register;
You have give the link wrong in your code
axios.post('http:/localhost:8000/register', data).then(
It should be
axios.post('http://localhost:8000/register', data).then(
You are missing a forward slash
I am trying to create a filter for my list of doctors, but it is not working.
I tried to follow some tutorials and it didn't work.
Where can I be wrong?
Follow my repository with the complete project, but my problem is in the index.js file (src / components / Doctors): Frontend Repository
I appreciate the help, because I've been trying to create a filter for more than 1 week and I can't.
Below, complete code from index.js
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import DoctorsActions from '~/store/ducks/doctors';
import MembersActions from '~/store/ducks/members';
import Can from '~/components/Can';
import Modal from '../Modal';
import Members from '~/components/Members';
import Button from '../../styles/components/Button';
import {
Editbutton,
Cancelbutton,
Savebutton,
Container,
Doctor,
MenuItem,
SearchField,
} from './styles';
class Doctors extends Component {
static propTypes = {
getDoctorsRequest: PropTypes.func.isRequired,
openDoctorModal: PropTypes.func.isRequired,
closeDoctorModal: PropTypes.func.isRequired,
createDoctorRequest: PropTypes.func.isRequired,
openMembersModal: PropTypes.func.isRequired,
activeTeam: PropTypes.shape({
name: PropTypes.string,
}),
doctors: PropTypes.shape({
data: PropTypes.arrayOf(
PropTypes.shape({
id: PropTypes.number,
nm_doctor: PropTypes.string,
})
),
doctorModalOpen: PropTypes.bool,
}).isRequired,
members: PropTypes.shape({
membersModalOpen: PropTypes.bool,
}).isRequired,
};
static defaultProps = {
activeTeam: null,
};
state = {
nm_doctor: '',
spc_doctor: '',
address_doctor: '',
district_doctor: '',
city_doctor: '',
state_doctor: '',
ph1_doctor: '',
ph2_doctor: '',
ph3_doctor: '',
email: '',
website: '',
sus: '',
tj: '',
plan_doctor: '',
calldate_doctor: '',
contact_colih: '',
comments: '',
};
componentDidMount() {
const { getDoctorsRequest, activeTeam } = this.props;
if (activeTeam) {
getDoctorsRequest();
}
}
handleInputChange = e => {
this.setState({ [e.target.name]: e.target.value });
};
handleSearchChange = e => {
this.setState({ [e.target.name]: e.target.value });
const doctorlist = e.target.filter(doctors =>
doctors[e.target.name].includes(e.target.value)
);
this.setState(doctorlist);
};
handleCreateDoctor = e => {
e.preventDefault();
const { createDoctorRequest } = this.props;
const {
nm_doctor,
spc_doctor,
address_doctor,
district_doctor,
city_doctor,
state_doctor,
ph1_doctor,
ph2_doctor,
ph3_doctor,
email,
website,
sus,
tj,
plan_doctor,
calldate_doctor,
contact_colih,
comments,
} = this.state;
createDoctorRequest(
nm_doctor,
spc_doctor,
address_doctor,
district_doctor,
city_doctor,
state_doctor,
ph1_doctor,
ph2_doctor,
ph3_doctor,
email,
website,
sus,
tj,
plan_doctor,
calldate_doctor,
contact_colih,
comments
);
};
render() {
const {
activeTeam,
openDoctorModal,
closeDoctorModal,
doctors,
openMembersModal,
members,
} = this.props;
const {
nm_doctor,
spc_doctor,
address_doctor,
city_doctor,
district_doctor,
state_doctor,
ph1_doctor,
ph2_doctor,
ph3_doctor,
email,
website,
sus,
tj,
plan_doctor,
calldate_doctor,
contact_colih,
comments,
} = this.state;
if (!activeTeam) return null;
return (
<Container>
<header>
<h1>{activeTeam.name}</h1>
<div>
<Can checkPermission="doctors_create">
<Button onClick={openDoctorModal}>Cadastrar Médico</Button>
<Button onClick={openMembersModal}>Convidar Membro</Button>
</Can>
</div>
</header>
{/* Mostra lista dos médicos cadastrados */}
<SearchField
placeholder="Procurar por....."
onChange={this.handleSearchChange}
onClick={() => console.log('buscar médico!')}
/>
{/* <Searchbutton
onClick={() => console.log('Botão teste para editar médico!')}
size="26"
/> */}
{doctors.data.map(doctor => (
<Doctor key={doctor.id}>
<Editbutton
onClick={() => console.log('Botão teste para editar médico!')}
size="28"
/>
<ul>
<li>
<b>{doctor.nm_doctor}</b>
</li>
<li>{doctor.spc_doctor}</li>
<li>
{doctor.address_doctor} - {doctor.district_doctor}
</li>
<li>
{doctor.ph1_doctor} / {doctor.ph2_doctor} / {doctor.ph3_doctor}
</li>
<li>
{doctor.city_doctor} - {doctor.state_doctor}
</li>
<li>{doctor.email}</li>
<li>{doctor.website}</li>
<li>
<b>SUS: </b>
{doctor.sus} - <b>TJ: </b>
{doctor.tj}
</li>
<li>
<b>Convênio: </b>
{doctor.plan_doctor}
</li>
<li>
<b>Última Visita: </b>
{doctor.calldate_doctor}
</li>
<li>
<b>Contato Colih: </b>
{doctor.contact_colih}
</li>
<li>
<b>Observações: </b>
{doctor.comments}
</li>
</ul>
</Doctor>
))}
{/* Término - mostrar médicos cadastrados */}
{/* //Modal Cadastrar Médicos começa aqui// */}
{doctors.doctorModalOpen && (
<Modal>
<h1>Novo Médico</h1>
<form onSubmit={this.handleCreateDoctor}>
<span>Nome do médico</span>
<input
type="text"
name="nm_doctor"
value={nm_doctor}
onChange={this.handleInputChange}
/>
<span>Especialidade</span>
<input
name="spc_doctor"
value={spc_doctor}
onChange={this.handleInputChange}
/>
<span>Endereço</span>
<input
name="address_doctor"
value={address_doctor}
onChange={this.handleInputChange}
/>
<span>Bairro</span>
<input
name="district_doctor"
value={district_doctor}
onChange={this.handleInputChange}
/>
<span>Cidade</span>
<input
name="city_doctor"
value={city_doctor}
onChange={this.handleInputChange}
/>
<span>Estado</span>
<select
name="state_doctor"
value={state_doctor}
onChange={this.handleInputChange}
>
<MenuItem value="ST">Selecione....</MenuItem>
{/* <MenuItem value="AM">Rio de Janeiro</MenuItem> */}
<MenuItem value="SP">São Paulo</MenuItem>
</select>
<span>Telefone 1</span>
<input
name="ph1_doctor"
value={ph1_doctor}
onChange={this.handleInputChange}
/>
<span>Telefone 2</span>
<input
name="ph2_doctor"
value={ph2_doctor}
onChange={this.handleInputChange}
/>
<span>Telefone 3</span>
<input
name="ph3_doctor"
value={ph3_doctor}
onChange={this.handleInputChange}
/>
<span>Email</span>
<input
name="email"
value={email}
onChange={this.handleInputChange}
/>
<span>Website</span>
<input
name="website"
value={website}
onChange={this.handleInputChange}
/>
<span>SUS</span>
<select name="sus" value={sus} onChange={this.handleInputChange}>
<MenuItem value="ST">Selecione....</MenuItem>
<MenuItem value="Sim">Sim</MenuItem>
<MenuItem value="Não">Não</MenuItem>
</select>
<span>TJ</span>
<select name="tj" value={tj} onChange={this.handleInputChange}>
<MenuItem value="ST">Selecione....</MenuItem>
<MenuItem value="Sim">Sim</MenuItem>
<MenuItem value="Não">Não</MenuItem>
</select>
<span>Convênio</span>
<input
name="plan_doctor"
value={plan_doctor}
onChange={this.handleInputChange}
/>
<span>Última Visita</span>
<input
type="date"
name="calldate_doctor"
value={calldate_doctor}
onChange={this.handleInputChange}
/>
<span>Contato Colih</span>
<input
name="contact_colih"
value={contact_colih}
onChange={this.handleInputChange}
/>
<span>Observações</span>
<input
name="comments"
value={comments}
onChange={this.handleInputChange}
/>
<Savebutton size="big" type="submit">
Salvar
</Savebutton>
<Cancelbutton
onClick={closeDoctorModal}
size="small"
color="gray"
>
Cancelar
</Cancelbutton>
</form>
</Modal>
// Modal Cadastrar Médicos termina aqui//
)}
{members.membersModalOpen && <Members />}
</Container>
);
}
}
const mapStateToProps = state => ({
activeTeam: state.teams.active,
members: state.members,
doctors: state.doctors,
});
const mapDispatchToProps = dispatch =>
bindActionCreators({ ...DoctorsActions, ...MembersActions }, dispatch);
export default connect(mapStateToProps, mapDispatchToProps)(Doctors);
Error after typing in the search bar
Screen with search bar
e.target is the component that fired the event, you can't call filter on it. You probably want to get the full list of doctors from state and filter that.
In your constructor:
constructor(props) {
super(props);
// ...
// set initial state
// you will need to populate these from your backend and make sure to set filtered to the full list when you retrieve your list of doctors
this.state = {
doctorList: [],
filtered: [],
}
}
In your handleSearchChange function:
handleSearchChange = e => {
// get the search term
const searchTerm = e.target.value;
// filter the full list of doctors
const filtered = this.state.doctorList.filter(doctor => doctor.name.includes(searchTerm));
// set the filtered list as state
this.setState({filtered: filtered});
}
And then in your render function, take the filtered list from state and render from that.
render() {
return(
// ...
// render each doctor in the filtered list
this.state.filtered.forEach(doctor => <DoctorListElement doctor={doctor}/>);
// ...
);
}
My react app is not redirecting to the dashboard page after submitting a form. I tried using react-router-dom Redirect function but still with no success. I then opt-in for Browser History. push but still no success.
for the latter trial, the URL changes to /dashboard but the component remains on the form page, it doesn't move to dashboard until I reload the page
form field
<form>
<Input
displayValidationErrors={displayValidationErrors("fullname", validators)}
name="fullname"
type="text"
label="Full Name"
onChange={(e) => handleInputChange(e.target.name, e.target.value)}
/>
<Input
displayValidationErrors={displayValidationErrors("password", validators)}
name="password"
type="password"
label="Password"
onChange={(e) => handleInputChange(e.target.name, e.target.value)}
/>
<Input
displayValidationErrors={displayValidationErrors("password2", validators)}
name="password2"
type="password"
label="Confirm Password"
onChange={(e) => handleInputChange(e.target.name, e.target.value)}
/>
<Input
displayValidationErrors={displayValidationErrors("email", validators)}
name="email"
type="email"
label="Email Address"
onChange={(e) => handleInputChange(e.target.name, e.target.value)}
/>
<Input
displayValidationErrors={displayValidationErrors(
"phone_number",
validators
)}
name="phone_number"
type="number"
label="Phone Number"
onChange={(e) => handleInputChange(e.target.name, e.target.value)}
/>
<Input
displayValidationErrors={displayValidationErrors("card_number", validators)}
value={data.card_number}
name="card_number"
type="text"
label="Card Number"
onChange={(e) => handleInputChange(e.target.name, e.target.value)}
/>
<Input
displayValidationErrors={displayValidationErrors("date", validators)}
value={data.date}
name="date"
type="text"
label="Expiry Date"
onChange={(e) => handleInputChange(e.target.name, e.target.value)}
/>
<Input
displayValidationErrors={displayValidationErrors("pin", validators)}
name="pin"
type="password"
label="PIN"
onChange={(e) => handleInputChange(e.target.name, e.target.value)}
/>
<div className="col-lg-12 loginbttm">
<div className=" login-btm login-button">
<Button
handleClick={onSubmit}
type="submit"
className="btn btn-primary"
label="SUBMIT"
disabled={!isFormValid(validators)}
/>
</div>
</div>
</form>;
onSubmit function
const onSubmit = (e) => {
e.preventDefault();
browserHistory.push("/dashboard");
};
Button Component
const Button = ({ type, className, handleClick, label, disabled }) => (
<button
type={type}
className={className}
onClick={handleClick}
disabled={disabled}
>
{label}
</button>
);
My app.js
function App() {
return (
<Router>
<div className="App">
<Switch>
<Route exact path="/dashboard">
<Dashboard />
</Route>
<Route exact path="/">
<Form />
</Route>
</Switch>
</div>
</Router>
);
}
export default App;
I don't see createBrowserHistory or something like <Router history={history}> so I guess you are using the default browser history. In that case you need withRouter to make it work:
import React from "react";
import { withRouter } from "react-router-dom";
function App() {
const onSubmit = (e) => {
e.preventDefault()
this.props.history.push("/personalInfo");
}
...
}
export default withRouter(App);
More about withRouter solution here
More about createBrowserHistory solution here
For functional component with react-router V5, you can also do with hooks:
import { useHistory } from "react-router-dom";
function App() {
let history = useHistory();
const onSubmit = (e) => {
e.preventDefault()
history.push('/dashboard');
}
return (
<Router>
<div className="App">
...
</div>
</Router>
);
}
Take a look at this to know more about useHistory
try using below. hope it'll help
this.props.history.push({
pathname: '/dashboard'
})
Another way of doing it with the function component -
import {withRouter} from "react-router-dom";
function SignIn({history}) {
const submit = (event) => {
event.preventDefault();
history.push("/profile");
}
....
}
export default withRouter(SignIn)