I want to implement redirect in my react project login. I googled it, and all use router. I've tried to add it to my code but I totally failed. This is my code, how can I implement router in the correct way?
App.js
import React, {useState, useEffect} from 'react';
import { Switch, Route, Redirect, Router } from 'react-router-dom';
import fire from './fire';
import Login from './Login';
import Home from './Home';
import './App.css';
function App() {
const [user, setUser] = useState('');
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [emailError, setEmailError] = useState('');
const [passwordError, setPasswordError] = useState('');
const [hasAccount,setHasAccount] = useState(false); //login e logout
const inputCleaner = () =>{
setEmail("");
setPassword("");
};
const clearErrors = () =>{
setEmailError("");
setPasswordError("");
};
const handleLogin = () =>{
clearErrors();
fire
.auth()
.signInWithEmailAndPassword(email,password)
.catch(err=>{
switch(err.code){
case "auth/invalid-email":
case "auth/user-disabled":
case "auth/user-not-found":
setEmailError(err.message);
break;
case "auth/wrong-password":
setPasswordError(err.message);
break;
}
});
};
const handleSignup = () =>{
clearErrors();
fire
.auth()
.createUserWithEmailAndPassword(email,password)
.catch(err=>{
switch(err.code){
case "auth/email-already-in-use":
case "auth/invalid-email":
setEmailError(err.message);
break;
case "auth/weak-password":
setPasswordError(err.message);
break;
}
});
};
const handleLogout = () =>{
fire.auth().signOut();
};
const authListerner = () =>{
fire.auth().onAuthStateChanged(user => {
if(user){
inputCleaner();
setUser(user);
}else{
setUser("");
}
})
};
useEffect (() =>{
authListerner();
},[]);
return (
<Router>
<div className="App">
{user ? (
<Home handleLogout={handleLogout} />
):(
<Login
email={email}
setEmail={setEmail}
password={password}
setPassword={setPassword}
handleLogin={handleLogin}
handleSignup={handleSignup}
hasAccount={hasAccount}
setHasAccount={setHasAccount}
emailError={emailError}
passwordError={passwordError}
/>
)}
</div>
</Router>
);
}
export default App;
Login.js
import React from 'react'
const Login = (props) =>{
const{
email,
setEmail,
password,
setPassword,
handleLogin,
handleSignup,
hasAccount,
setHasAccount,
emailError,
passwordError
} = props;
return(
<section className="login">
<div className="loginContainer">
<label>Email</label>
<input
type="text"
autoFocus
required
value ={email}
onChange ={e => setEmail(e.target.value)}
/>
<p className="errorMsg">{emailError}</p>
<label>Password</label>
<input
type="password"
autoFocus
required
value ={password}
onChange ={e => setPassword(e.target.value)}
/>
<p className="errorMsg">{passwordError}</p>
<div className="btnContainer">
{hasAccount ? (
<>
<button onClick={handleLogin}>Accedi</button>
<p>Don't have an account?<span onClick={ () => setHasAccount(!hasAccount)}>Sign up</span></p>
</>
) : (
<>
<button onClick={handleSignup}>Sign up</button>
<p>Have an account?<span onClick={ () => setHasAccount(!hasAccount)} >Sign in</span></p>
</>
)}
</div>
</div>
</section>
)
};
export default Login;
Home.js
import React from 'react';
const Home = ({handleLogout}) =>{
return(
<section className="home">
<nav>
<h2>Benvenuti</h2>
<button onClick={handleLogout}>Esci</button>
</nav>
</section>
);
};
export default Home;
I need to redirect to home after login, because I have to hidden the private information about users. To autenticate, it runs firebase, and I've written the functions in another component named fire.js, but to my mind isn't relevant to solve this problem.
Here is an example for you:
<Switch>
<Route exact path="/">
{user ? <Redirect to="/Home" /> : <Login />}
</Route>
</Switch>
Related
I am working on firebase authentication. I have made login, logout(on home), home pages. All are working fine. But when I try to login after I have changed something in router or in my code it works perfectly, that is redirects to Home. But when I login after logout, It does not work and reloads the same login page.
Also when isLoggedIn is set true after first try, it reloads login component. When I manually change url to /home then it works fine.
Here is my code.
App js
import Signup from "./Signup";
import Login from "./Login";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import Home from "./Home";
import ProtectedRoutes from "../ProtectedRoutes";
export default function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/">
<Route
path="home"
element={
<ProtectedRoutes
isLoggedIn={JSON.parse(localStorage.getItem("isLoggedIn"))}
>
<Home />
</ProtectedRoutes>
}
/>
<Route path="login" element={<Login />} />
<Route path="signup" element={<Signup />} />
</Route>
</Routes>
</BrowserRouter>
);
}
Login
import React from "react";
import { useRef, useState } from "react";
import { Button, Card, Form, Alert, Container } from "react-bootstrap";
import { signInWithEmailAndPassword } from "firebase/auth";
import { auth } from "../firebaserc";
import { Link, useNavigate } from "react-router-dom";
export default function Login() {
const emailRef = useRef();
const passwordRef = useRef();
const [error, setError] = useState("");
const [loading, setLoading] = useState(false);
const navigate = useNavigate();
const handleSubmit = (e) => {
e.preventDefault();
signInWithEmailAndPassword(
auth,
emailRef.current.value,
passwordRef.current.value
)
.then((userCredential) => {
// Signed in
const user = userCredential.user;
// ...
console.log(user);
localStorage.setItem("isLoggedIn", true);
if (JSON.parse(localStorage.getItem("isLoggedIn"))) {
navigate("/home");
}
setError("");
})
.catch((error) => {
setError(error.message);
});
};
return (
<>
<Container
className="d-flex align-items-center justify-content-center"
style={{
minHeight: "100vh",
}}
>
<div
className="w-100"
style={{
maxWidth: "400px",
}}
>
<Card>
<Card.Body>
<h2 className="text-center mb-3">Login</h2>
{error && <Alert variant="danger">{error}</Alert>}
<Form onSubmit={handleSubmit}>
<Form.Group id="email" className="mb-2">
<Form.Label>Email</Form.Label>
<Form.Control type="email" ref={emailRef} required />
</Form.Group>
<Form.Group id="password" className="mb-2">
<Form.Label>Password</Form.Label>
<Form.Control type="password" ref={passwordRef} required />
</Form.Group>
<Button disabled={loading} className="w-100 mt-2" type="submit">
Login
</Button>
</Form>
</Card.Body>
</Card>
<div className="w-100 text-center mt-2">
New here? <Link to="/signup">Signup</Link>
</div>
</div>
</Container>
</>
);
}
Signup
import React from "react";
import { useRef, useState } from "react";
import { Button, Card, Form, Alert, Container } from "react-bootstrap";
import { createUserWithEmailAndPassword } from "firebase/auth";
import { auth } from "../firebaserc";
import { Link, useNavigate } from "react-router-dom";
export default function Signup() {
const emailRef = useRef();
const passwordRef = useRef();
const [error, setError] = useState("");
const [loading, setLoading] = useState(false);
const navigate = useNavigate();
const handleSubmit = (e) => {
e.preventDefault();
createUserWithEmailAndPassword(
auth,
emailRef.current.value,
passwordRef.current.value
)
.then((userCredential) => {
// Signed in
const user = userCredential.user;
console.log(user);
setError("");
navigate("/home");
localStorage.setItem("isLoggedIn", true);
// ...
})
.catch((error) => {
setError(error.message);
// ..
});
};
return (
<>
<Container
className="d-flex align-items-center justify-content-center"
style={{
minHeight: "100vh",
}}
>
<div
className="w-100"
style={{
maxWidth: "400px",
}}
>
<Card>
<Card.Body>
<h2 className="text-center mb-3"> Sign Up</h2>
{error && <Alert variant="danger">{error}</Alert>}
<Form onSubmit={handleSubmit}>
<Form.Group id="email" className="mb-2">
<Form.Label>Email</Form.Label>
<Form.Control type="email" ref={emailRef} required />
</Form.Group>
<Form.Group id="password" className="mb-2">
<Form.Label>Password</Form.Label>
<Form.Control type="password" ref={passwordRef} required />
</Form.Group>
<Button disabled={loading} className="w-100 mt-2" type="submit">
Sign Up
</Button>
</Form>
</Card.Body>
</Card>
<div className="w-100 text-center mt-2">
Already have an account <Link to="/login">Login</Link>
</div>
</div>
</Container>
</>
);
}
Home
import React from "react";
import { Button } from "react-bootstrap";
import { auth } from "../firebaserc";
import { signOut } from "firebase/auth";
import { useNavigate } from "react-router-dom";
export default function Home() {
const navigate = useNavigate();
const handleLogout = () => {
signOut(auth)
.then(() => {
// Sign-out successful.
localStorage.removeItem("isLoggedIn");
navigate("/login", { replace: true });
})
.catch((error) => {
// An error happened.
console.log(error.message);
});
};
return (
<div>
Home
<Button onClick={handleLogout}>Logout</Button>
</div>
);
}
Protected Routes
import { Navigate } from "react-router-dom";
const ProtectedRoutes = ({ isLoggedIn, children }) => {
if (!isLoggedIn) {
return <Navigate to="/login" replace />;
}
return children;
};
export default ProtectedRoutes;
Let's say you want to make a React App refresh ,
Simply
React.useEffect(() => {
doSomething();
}, [doSomething, IsAuthenticated ]);
once this values change it will update this component
This value need to be observable
firebase gives you that
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
// User is signed in.
} else {
// No user is signed in.
}
});
https://firebase.google.com/docs/auth/web/manage-users
and with react you can also make
firebase.auth().onAuthStateChanged((user) => {
if (user) {
handleLogin(user);
} else {
Logout();
}
});
function Logout() {
setAuthintecated(false)
};
Also here some resource for you
https://www.freecodecamp.org/news/react-firebase-authentication-and-crud-operations/
GoodLuck
I'm using Laravel on the backend and react.js on the frontend , when I try to login it will redirect to the home ("/") but when I refresh the page I am redirected to login page again. I am using rote protection file which takes component as a parameter and all the components passed in protected route are only accessible by logged in users.. after logging in when I try to access protected pages I am redirected to login page.. can any body help?
app.js
function App() {
return (
<div className="App">
{/* <AuthContextProvider> */}
<BrowserRouter>
<Switch>
<Route path = "/login"><Login/></Route>
<Route path= "/register"><Register/></Route>
<Route path = "/add"><AuthProtection component = {AddProduct}/> </Route>
<Route path = "/update"><AuthProtection component = {UpdateProduct}/> </Route>
<Route path = "/search"><AuthProtection component = {Search}/> </Route>
<Route path = "/"><AuthProtection component = {Home}/> </Route>
</Switch>
</BrowserRouter>
{/* </AuthContextProvider> */}
</div>
);
}
export default App;
login.js
export const Login = () => {
const history = useHistory()
const [email, setemail] = React.useState("")
const [password, setpass] = React.useState("")
const loginuser = e =>{
e.preventDefault();
axios.defaults.withCredentials = true;
let data = {email,password}
axios.get('http://localhost:8000/sanctum/csrf-cookie').then(response => {
console.log(response)
axios.post('http://localhost:8000/login',data ,{
headers: {
'Content-Type': 'application/json',
"Accept": "application/json",
'X-XSRF-TOKEN': (() => {
const name = 'XSRF-TOKEN'
const cookies = '; ' + document.cookie
const parts = cookies.split('; ' + name + '=')
const value = parts.length == 2 ? parts.pop().split(';').shift() : null
console.log('>>> XSRF-TOKEN', value)
return value
})(),
},
}).then(response => {
localStorage.setItem("user-info" , JSON.stringify(response.config.headers["X-XSRF-TOKEN"]))
Auth.authenticate();
history.push("/");
});
});
}
return (
<>
<Header/>
<div>
<div className="wrapper fadeInDown">
<div id="formContent">
{/* Tabs Titles */}
{/* Icon */}
<div className="fadeIn first">
</div>
{/* Login Form */}
<form onSubmit = {loginuser}>
<input type="text" value={email} onChange={(e)=>setemail(e.target.value)} className="fadeIn second" placeholder="login" />
<input type="password" value={password} onChange={(e)=>setpass(e.target.value)} className="fadeIn third" placeholder="password" />
<button type="submit" className="fadeIn fourth btn btn-primary" >LOGIN</button>
</form>
{/* Remind Passowrd */}
<div id="formFooter">
<a className="underlineHover" href="#">Forgot Password?</a>
</div>
</div>
</div>
</div>
</>
)
}
Auth.js
const Auth = {
isAuthenticated: false,
authenticate() {
this.isAuthenticated = true;
},
signout() {
this.isAuthenticated = false;
},
getAuth() {
return this.isAuthenticated;
}
};
export default Auth;
protectedRoutes.js
import React from 'react'
import { useHistory } from 'react-router'
import Auth from './Auth'
import { AuthContext } from './AuthContext';
export const AuthProtection = (props) => {
console.log(props)
const history = useHistory()
let ProtectedTemplate = props.component
console.log(Auth.getAuth())
React.useEffect(()=>{
if( !Auth.getAuth() ){
history.push("/login")
}
})
return (
<div>
<ProtectedTemplate/>
</div>
)
}
I'm having a problem where my code does not want to work while redirecting to the main page which is Dashboard.js. That file is just an UI I'm working on. I'm currently working on a signup and login page. Here is the code.
Signup.js
import { Form, Button, Card, Alert } from "react-bootstrap"
import { useAuth } from "../contexts/AuthContext"
import { Link, useHistory } from "react-router-dom"
export default function Signup() {
const emailRef = useRef()
const passwordRef = useRef()
const passwordConfirmRef = useRef()
const { signup } = useAuth()
const [error, setError] = useState("")
const [loading, setLoading] = useState(false)
const history = useHistory()
async function handleSubmit(e) {
e.preventDefault()
if (passwordRef.current.value !== passwordConfirmRef.current.value) {
return setError("Passwords do not match")
}
try {
setError("")
setLoading(true)
await signup(emailRef.current.value, passwordRef.current.value)
history.push("/")
} catch {
setError("Failed to create an account")
}
setLoading(false)
}
return (
<>
<Card>
<Card.Body>
<h2 className="text-center mb-4">Sign Up</h2>
{error && <Alert variant="danger">{error}</Alert>}
<Form onSubmit={handleSubmit}>
<Form.Group id="email">
<Form.Label>Email</Form.Label>
<Form.Control type="email" ref={emailRef} required />
</Form.Group>
<Form.Group id="password">
<Form.Label>Password</Form.Label>
<Form.Control type="password" ref={passwordRef} required />
</Form.Group>
<Form.Group id="password-confirm">
<Form.Label>Password Confirmation</Form.Label>
<Form.Control type="password" ref={passwordConfirmRef} required />
</Form.Group>
<Button disabled={loading} className="w-100" type="submit">
Sign Up
</Button>
</Form>
</Card.Body>
</Card>
<div className="w-100 text-center mt-2">
Already have an account? <Link to="/login">Log In</Link>
</div>
</>
)
}
AuthContext.js
import { auth } from "../firebase"
const AuthContext = React.createContext()
export function useAuth() {
return useContext(AuthContext)
}
export function AuthProvider({ children }) {
const [currentUser, setCurrentUser] = useState()
const [loading, setLoading] = useState(true)
function signup(email, password) {
return auth.createUserWithEmailAndPassword(email, password)
}
function login(email, password) {
return auth.signInWithEmailAndPassword(email, password)
}
function logout() {
return auth.signOut()
}
function resetPassword(email) {
return auth.sendPasswordResetEmail(email)
}
function updateEmail(email) {
return currentUser.updateEmail(email)
}
function updatePassword(password) {
return currentUser.updatePassword(password)
}
useEffect(() => {
const unsubscribe = auth.onAuthStateChanged(user => {
setCurrentUser(user)
setLoading(false)
})
return unsubscribe
}, [])
const value = {
currentUser,
login,
signup,
logout,
resetPassword,
updateEmail,
updatePassword
}
return (
<AuthContext.Provider value={value}>
{!loading && children}
</AuthContext.Provider>
)
}
Login.js
import { Form, Button, Card, Alert } from "react-bootstrap"
import { useAuth } from "../contexts/AuthContext"
import { Link, useHistory } from "react-router-dom"
export default function Login() {
const emailRef = useRef()
const passwordRef = useRef()
const { login } = useAuth()
const [error, setError] = useState("")
const [loading, setLoading] = useState(false)
const history = useHistory()
async function handleSubmit(e) {
e.preventDefault()
try {
setError("")
setLoading(true)
await login(emailRef.current.value, passwordRef.current.value)
history.push("/")
} catch {
setError("Failed to log in")
}
setLoading(false)
}
return (
<>
<Card>
<Card.Body>
<h2 className="text-center mb-4">Log In</h2>
{error && <Alert variant="danger">{error}</Alert>}
<Form onSubmit={handleSubmit}>
<Form.Group id="email">
<Form.Label>Email</Form.Label>
<Form.Control type="email" ref={emailRef} required />
</Form.Group>
<Form.Group id="password">
<Form.Label>Password</Form.Label>
<Form.Control type="password" ref={passwordRef} required />
</Form.Group>
<Button disabled={loading} className="w-100" type="submit">
Log In
</Button>
</Form>
<div className="w-100 text-center mt-3">
<Link to="/forgot-password">Forgot Password?</Link>
</div>
</Card.Body>
</Card>
<div className="w-100 text-center mt-2">
Need an account? <Link to="/signup">Sign Up</Link>
</div>
</>
)
}
App.js
import React from "react"
import Signup from "./Signup"
import { Container } from "react-bootstrap"
import { AuthProvider } from "../contexts/AuthContext"
import { BrowserRouter as Router, Switch, Route } from "react-router-dom"
import Dashboard from "./Dashboard"
import Login from "./Login"
import PrivateRoute from "./PrivateRoute"
import ForgotPassword from "./ForgotPassword"
import UpdateProfile from "./UpdateProfile"
function App() {
return (
<Container
className="d-flex align-items-center justify-content-center"
style={{ minHeight: "100vh" }}
>
<div className="w-100" style={{ maxWidth: "400px" }}>
<Router>
<AuthProvider>
<Switch>
<PrivateRoute exact path="/" component={Dashboard} />
<PrivateRoute path="/update-profile" component={UpdateProfile} />
<Route path="/signup" component={Signup} />
<Route path="/login" component={Login} />
<Route path="/forgot-password" component={ForgotPassword} />
</Switch>
</AuthProvider>
</Router>
</div>
</Container>
)
}
export default App
index.js
import ReactDOM from "react-dom"
import App from "./components/App"
import "bootstrap/dist/css/bootstrap.min.css"
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById("root")
)
The problem I'm having in this code is at the useHistory part in Login.js(Line 12 and 21) and Signup.js(Line 13 and 26). Included the other codes because I think that all of the code might be linked to one another.
Thank you.
In both login and signup scenarios you are redirecting to home page immediately after a successful call. However your context value is updating only when the onAuthStateChanged function callback is called by firebase. There can be a small lag during this time and hence you aren't able to redirect to the PrivateRoute correctly.
A reliable way of handling this would be to wait for the currentUser data to be available from context like
const { login, currentUser } = useAuth()
async function handleSubmit(e) {
e.preventDefault()
try {
setError("")
setLoading(true)
await login(emailRef.current.value, passwordRef.current.value)
} catch {
setError("Failed to log in");
}
setLoading(false)
}
useEffect(() => {
if(currentUser) {
history.push('/');
}
}, [currentUser]);
A similar handling can be done in signup component too. This way even if you try to visit the login or signup routes directly from browser url, you will be redirected to home page if the user is already logged in.
Trying to create sign in and sign up with react and firebase and got the error setEmail is not a function when trying to fill the input for the email, if i try to fill the input for password, i get the same error but for setPassword setPassword is not a function App.js
Here is my app.js
import React, {useState, useEffect} from 'react';
import './App.css';
import './Components/Feed/styles/_properties.scss'
import Home from './Pages';
import {BrowserRouter as Router, Switch, Route} from 'react-router-dom';
import SignInPage from './Pages/signin';
import SignUpPage from './Pages/signup';
import Feed from './Pages/feed';
import fire from './fire';
function App() {
const [user, setUser] = useState('');
const [email, setEmail] = useState('');
const [ password, setPassword] = useState('');
const [emailError, setEmailError] = useState('');
const [passwordError, setPasswordError] = useState('');
const [hasAccount, setHasAccount] = useState('');
const clearInputs = () => {
setEmail('')
setPassword('');
}
const clearErrors = () => {
setEmailError('');
setPasswordError('');
}
const handleLogin = () => {
clearErrors();
fire
.auth()
.signInWithEmailAndPassword(email,password)
.catch(err => {
switch(err.code){
case 'auth/Invalid-email':
case 'auth/user-disabled':
case 'auth/user-not-found':
setEmailError(err.message);
break;
case 'auth/wrong-password':
setPasswordError(err.message);
break;
}
});
};
const handleSignUp = () => {
clearErrors();
fire
.auth()
.createuserWithEmailAndPassword(email,password)
.catch(err => {
switch(err.code){
case 'auth/email-already-In-use':
case 'auth/invalid-email':
setEmailError(err.message);
break;
case 'auth/weak-password':
setPasswordError(err.message);
break;
};
});
};
const handleLogout = () => {
fire.auth().signOut();
};
const authListener = () => {
fire.auth().onAuthStateChanged(user =>{
if(user){
clearInputs();
setUser(user);
}else{
setUser('')
};
});
};
useEffect(() => {
authListener();
}, []);
return (
<Router>
<Switch>
{user ? (
<Home handleLogout={handleLogin}/>
):(
<SignInPage email={email}
setEmail={setEmail}
emailError ={emailError}
setEmailError ={setEmailError}
password={password}
setPassword={setPassword}
handleLogin={handleLogin}
handleSignUp={handleSignUp}
hasAccount={hasAccount}
setHasAccount={setHasAccount}
passwordError={passwordError}/>
)}
<Route path='/signup' component={SignUpPage} exact />
<Route path = '/feed' component={Feed} exact />
</Switch>
</Router>
);
}
export default App;
And here is my Signin.js
import React from 'react';
import './SigninElements.css'
const SignIn = (props) => {
const {
email,
setEmail,
password,
setPassword,
handleSignIn,
handleSignup,
hasAccount,
setHasAccount,
emailError,
passwordError
} = props;
return (
<section className='signin'>
<div className='signinContainer'>
<label>Username or Email</label>
<input
type='text'
outoFocus
required
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
<p className='errorMsg'>{emailError}</p>
<label>Password</label>
<input
type='password'
required
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
<p className='errorMsg'>{passwordError}</p>
<div className='btnContainer'>
{hasAccount ? (
<>
<button onClick={handleSignIn}> Sign In</button>
<p> Don't have an account ? <span onclick={() => setHasAccount(!hasAccount)}>Sign up</span></p>
</>
) : (
<>
<button onClick={handleSignup}> Sign In</button>
<p> Have an account ? <span onClick={() => setHasAccount(!hasAccount)}>Sign in</span></p>
</>
)}
</div>
</div>
</section>
)
}
export default SignIn;
I searched what could be the problem, but I have no idea. I think it could be the way I'm calling the props. I might be wrong lol. I would really appreciate any help.
Because you are using the setEmail prop as a function, but not passing it that way. That's why you are getting that error. Try in a following way.
<SignInPage setEmail={setEmail} .../>
And in SignInPage change the code to
onChange={handleChange}
const handleChange = (e) => {
props.setEmail(e.target.value);
}
or
onChange={(e) => props.setEmail(e.target.value)}
Here's my app component that renders an input for user to type in. What I want to achieve is that whatever input that the user writes in will be passed down to the Films component. That text is then will be used as a query param to get data from an api endpoint
import React, { useState } from "react";
import Films from "../Films";
import { BrowserRouter as Router, Route } from "react-router-dom";
import "./style.css";
const App = () => {
const [text, setText] = useState("");
const [redirect, setRedirect] = useState(false);
const onSubmit = (event) => {
setRedirect(true);
};
return (
<Router>
<div>
<p className="films-analysis-service">Films Analysis Service </p>
<form id="input-form" onSubmit={onSubmit}>
<input
type="text"
id="input-box"
value={text}
onChange={(e) => setText(e.target.value)}
/>
<button className="button" type="submit">
Search
</button>
</form>
{redirect && (
<Route
exact
path="/films"
render={(props) => <Films text={text} />}
/>
)}
</div>
</Router>
);
};
export default App;
This is my Films component:
import React, { useEffect, useState } from "react";
import "./style.css";
const axios = require("axios");
const Films = ({ text }) => {
const [movies, setMovies] = useState([]);
const fetchMoviesByDirectorName = () => {
let config = {
headers: { Authorization: apiKey },
params: {
directorName: text, //the text that is passed down from App component
},
};
axios.get(filmsEndpointURL, config);
};
useEffect(() => {
fetchMoviesByDirectorName();
}, [movies]);
return (
...
);
};
export default Films;
At the moment I'm just trying to print out the data that I would get back but unfortunately I don't think my input value is passed down properly. I don't think my usage of Route is correct.. and it's not redirecting to /films component. What changes should I do to my App.js?
Make sure to do event.preventDefault() in onSubmit
const onSubmit = (event) => {
event.preventDefault(); //<----- like this
setRedirect(true);
};
You can use Redirect to navigate to Films not Route.
Refactored code (using Redirect)
<Router>
<div>
<p className="films-analysis-service">Films Analysis Service </p>
<form id="input-form" onSubmit={onSubmit}>
<input
type="text"
id="input-box"
value={text}
onChange={(e) => setText(e.target.value)}
/>
<button className="button" type="submit">
Search
</button>
</form>
<Route exact path="/films" render={(props) => <Films text={text} {...props}/>} /> //<----see here
{redirect && <Redirect to="/films" />} //<----see here
</div>
<Route></Route>
</Router>;
You can also use history object to navigate to Films
import { createBrowserHistory } from "history";
const customHistory = createBrowserHistory();
const App = () => {
const [text, setText] = useState("");
const [redirect, setRedirect] = useState(false);
const onSubmit = (event) => {
// setRedirect(true);//<----no need
customHistory.push("/films");
};
return (
<Router history={customHistory}>
<div>
<p className="films-analysis-service">Films Analysis Service </p>
<form id="input-form" onSubmit={onSubmit}>
<input
type="text"
id="input-box"
value={text}
onChange={(e) => setText(e.target.value)}
/>
<button className="button" type="submit">
Search
</button>
</form>
<Route exact path="/films" render={(props) => <Films text={text} />} />
</div>
</Router>
);
};
export default App;