Having trouble routing to next page after button click - ionic-framework

Need help routing to another page. I have page that enter user profile to firestore database and once Submit page will route to next page (WelcomePage.jsx).
Adding to Firestore database is working fine but the routing to next page is failing after click on the submiting button. I don't receive any error in the console log.
Below are my coding:
ProfilePage.jsx
import React,{useState} from 'react'
import {auth} from '../firebaseconfig';
import { person,calendarNumber,location} from 'ionicons/icons';
import '../components/stylesheet.css';
import {IonContent,IonPage,IonLabel,IonCard,IonList,IonItem,IonIcon,
IonInput,IonButton,IonHeader,IonToolbar,IonTitle,IonSelect,IonSelectOption } from '#ionic/react';
import { useAuth } from '../auth';
import { firestore } from '../firebaseconfig';
import { useForm } from 'react-hook-form';
import * as Yup from 'yup';
import { yupResolver } from '#hookform/resolvers/yup';
import WelcomePage from './WelcomePage';
import { Redirect } from 'react-router';
export default function ProfilePage(){
const { loggedIn } = useAuth();
const validationSchema = Yup.object().shape({
fullname: Yup.string()
.required('Enter Name'),
age: Yup.string()
.required('Enter Age'),
gender: Yup.string()
.required('Select Gender'),
location: Yup.string()
.required('Enter Location')
});
const formOptions = {resolver: yupResolver(validationSchema)}
const { register, handleSubmit, reset, formState } = useForm(formOptions);
const { errors } = formState;
const [patName, setPatName]=useState('');
const [patAge, setPatAge]=useState('');
const [patGender, setPatGender]=useState('');
const [patLocation, setPatLocation]=useState('');
const patPhoneNumber = auth.currentUser.phoneNumber.toString();
// const handleSave = async () => {
// const userData = {patAge, patName, patGender,patLocation,patPhoneNumber};
// const usersRef = firestore.collection('pat_profile').doc(auth.currentUser.uid).set({userData});
// };
const onSubmit = (data, e) => {
const {fullname,age,gender,location}= data;
const userData = {fullname,age,gender,location,patPhoneNumber};
firestore.collection('pat_profile').doc(auth.currentUser.uid).set({fullname,age,gender,location,patPhoneNumber});
return <Redirect to= "WelcomePage" />;
};
const onError = (errors, e) => console.log(errors, e);
return (
<IonPage>
<IonHeader>
<IonToolbar>
<IonTitle className="profileheader">Profile Details</IonTitle>
</IonToolbar>
</IonHeader>
<IonContent className="ion-padding ion-content">
<form onSubmit={handleSubmit(onSubmit, onError)}>
<IonCard className="card-profile">
<IonList>
<IonItem className="item-background-color item-text">
<IonInput autofocus name="fullname"
placeholder="Enter Name" required {...register("fullname")}
value={patName} onIonChange={(event) => setPatName(event.detail.value)}
/>
<IonIcon icon={person} />
</IonItem>
</IonList>
<IonList>
<IonItem className="item-background-color item-text">
<IonInput type="number" required name="age"
placeholder="Age" {...register("age")}
value={patAge} onIonChange={(event) => setPatAge(event.detail.value)}
/>
<IonIcon icon={calendarNumber} />
</IonItem>
</IonList>
<IonList>
<IonItem className="item-background-color item-text">
<IonLabel>Gender</IonLabel>
<IonSelect required placeholder="Select" value={patGender} interface="popover" name="gender" {...register("gender")}
onIonChange={(event) => setPatGender(event.detail.value)}>
<IonSelectOption value="Female">Female</IonSelectOption>
<IonSelectOption value="Male">Male</IonSelectOption>
</IonSelect>
</IonItem>
</IonList>
<IonList lines="none">
<IonItem className="item-background-color item-text">
<IonInput
placeholder="Location" required {...register("location")} name="location"
value={patLocation} onIonChange={(event) => setPatLocation(event.detail.value)}
/>
<IonIcon icon={location} />
</IonItem>
</IonList>
</IonCard>
<IonButton className="item-button-reg ion-color-button" size="default" expand="block" type="submit" > REGISTER</IonButton>
</form>
</IonContent>
</IonPage>
);
}
WelcomePage.jsx
import React from "react";
import {auth} from '../firebaseconfig';
import { person,calendarNumber,location} from 'ionicons/icons';
import '../components/stylesheet.css';
import {IonContent,IonPage,IonLabel,IonCard,IonList,IonItem,IonIcon,
IonInput,IonButton,IonHeader,IonToolbar,IonTitle,IonSelect,IonSelectOption } from '#ionic/react';
export default function WelcomePage(){
return(
<IonPage>
<IonContent className="ion-padding phreg-content">
<IonLabel>Welcome</IonLabel>
</IonContent>
</IonPage>
);
}

I think.. may be you have problem or grammar error.
First, exist WelcomePage path in Route?
<Route path="/WelcomePage" component={WelcomePage}/>
And, Why don't you use <Router /> ?
example these.
<Router>
<Switch>
<PrivateRoute exact path="/" component={Home} />
<Route path="/users/sign_in" component={SingIn}/>
<Route path="/users/sign_up" component={SignUp}/>
</Switch>
</Router>
Or use this.
<Redirect to={{
pathname: '/WelcomePage'
}}/>

Related

Tab Color disorder and single click ripple effect disappears after I add active tabs

Here's my header copmponent where I try to apply active tabs effect, the text completely disappers.
Header.js
import {
AppBar,
Toolbar,
useScrollTrigger,
Typography,
Tabs,
Tab,
Button,
} from "#mui/material";
import DeveloperModeIcon from "#mui/icons-material/DeveloperMode";
import { Box } from "#mui/system";
import { styled } from "#mui/material/styles";
import { Link } from "react-router-dom";
const Header = () => {
const [value, setValue] = useState(window.location.pathname);
function ElevationScroll(props) {
const { children } = props;
const trigger = useScrollTrigger({
disableHysteresis: true,
threshold: 0,
});
return React.cloneElement(children, {
elevation: trigger ? 4 : 0,
});
}
const TabComponent = styled(Tab)(({ theme }) => ({
fontWeight: 600,
fontSize: "1rem",
textTransform: "none",
// color: theme.palette.common.white,
}));
const onTabChangeHandler = (event, newValue) => {
setValue(newValue);
};
return (
<React.Fragment>
<ElevationScroll>
<AppBar position="fixed">
<Toolbar>
<DeveloperModeIcon sx={{ fontSize: "3rem" }} />
<Typography variant="h4">Lopxhan Development</Typography>
<Tabs
sx={{ marginLeft: "auto" }}
value={value}
onChange={onTabChangeHandler}
aria-label="secondary tabs example"
>
<TabComponent label="Home" component={Link} to="/" value="/" />
<TabComponent
label="Services"
component={Link}
to="/services"
value="/services"
disableRipple
/>
<TabComponent
label="Projects"
component={Link}
to="/projects"
value="/projects"
/>
<TabComponent
label="About Us"
component={Link}
to="/aboutus"
value="/aboutus"
/>
<TabComponent
label="Conatct Us"
component={Link}
to="/contactus"
value="/contactus"
/>
</Tabs>
<Button
variant="contained"
color="secondary"
sx={{
borderRadius: "50px",
fontWeight: 600,
}}
>
Get a Quote
</Button>
</Toolbar>
</AppBar>
</ElevationScroll>
<Box
sx={[
(theme) => ({
marginBottom: {
...theme.mixins.toolbar,
},
}),
]}
/>
</React.Fragment>
);
};
export default Header;
Theme.js
const arcBlue = "#0B72B9";
const arcOrange = "#e67700";
const arcGrey = "#868686";
export const appTheme = createTheme({
palette: {
common: {
blue: arcBlue,
orange: arcOrange,
white: "#fff",
},
primary: {
main: arcBlue,
},
secondary: {
main: arcOrange,
},
},
});
App.js
import { Routes, Route } from "react-router-dom";
import { ThemeProvider } from "#mui/material/styles";
import Header from "./components/UI/Header";
import { appTheme } from "./components/UI/Theme";
import HomePage from "./components/pages/HomePage";
import ServicesPage from "./components/pages/ServicesPage";
import ProjectsPage from "./components/pages/ProjectsPage";
import GetAQuotePage from "./components/pages/GetAQuotePage";
import AboutUsPage from "./components/pages/AboutUsPage";
import ContactUsPage from "./components/pages/ContactUsPage";
function App() {
return (
<ThemeProvider theme={appTheme}>
<Header />
<Routes>
<Route path="/" element={<HomePage />} />
<Route path="/services" element={<ServicesPage />} />
<Route path="/projects" element={<ProjectsPage />} />
<Route path="/aboutus" element={<AboutUsPage />} />
<Route path="/contactus" element={<ContactUsPage />} />
<Route path="/getaquote" element={<GetAQuotePage />} />
</Routes>
</ThemeProvider>
);
}
export default App;
I tried applying textColor and indicatorColor to Tabs, and its kinda somehow shows the tab text but ripple effect changes to double click. Also ripple effect on tab changes to double click as soon as I add active tab effect.

I make mistakes in Next js, but I dont know where

I use Next js dont correct, but I dont understend why. I saw github repository other programers, but I dont see where I made mistakes. That I make mistakes tolt me employer. The only one differences I found is I use only globals.css, but I think it dont mitakes. I want to grow as a programer, but I cant become better whisout your help. Please told me where i make mistakes in Next js.
My github repository: https://github.com/Yury11111111111/books-catalog
Code:
componets/BookComponent.js
import React from "react";
import Link from "next/link"
import Image from 'react-bootstrap/Image'
const BookComponent = (props) => {
return (
<>
<Link href={`/book/${props.book.id}`}>
<div className="book__wraper">
{props.book?.volumeInfo?.categories ?
<div className="book__category">{props.book?.volumeInfo?.categories[0]}</div>
: <></>}
{props.book?.volumeInfo?.imageLinks?.thumbnail ? (
<Image
src={props.book?.volumeInfo?.imageLinks?.thumbnail}
alt="book cover"
className="book__img"
/>
) : (
<Image className="noCover" src="https://rublevbar.com/files/rublevbar/image/no_product.jpg" alt="no book cover" />
)}
<div className="book__title">{props.book?.volumeInfo?.title}</div>
<div className="book__autors">{props.book?.volumeInfo?.authors}</div>
</div></Link>
</>
);
};
export default BookComponent;
pages/_app.js
import "../styles/globals.css";
import { store } from "../store";
import { Provider } from "react-redux";
import 'bootstrap/dist/css/bootstrap.min.css';
function MyApp({ Component, pageProps }) {
return (
<Provider store={store}>
<Component {...pageProps} />
</Provider>
);
}
export default MyApp;
pages/index.js
import React, { useEffect, useState } from "react";
import { useSelector, useDispatch } from "react-redux";
import { fetchBooksData } from "../slices/booksSlice";
import Head from "next/head";
import { Container, Form, Row, Col, Button, InputGroup } from "react-bootstrap";
import BookComponent from "../componets/BookComponent";
export default function Home() {
const books = useSelector((state) => state.books.books);
const name = useSelector((state) => state.books.name);
const startIndex = useSelector((state) => state.books.startIndex);
const error = useSelector((state) => state.books.error);
const [resultName, setResultName] = useState("book");
const [resultStartIndex, setResultStartIndex] = useState(0);
const [resultCategory, setResultCategory] = useState("all");
const [resultSort, setResultSort] = useState("relevance");
const dispatch = useDispatch();
useEffect(() => {
dispatch(
fetchBooksData({
name: resultName,
startIndex: resultStartIndex,
category: resultCategory,
sort: resultSort,
})
);
}, [resultName, resultStartIndex, resultCategory, resultSort, dispatch]);
if (error === "error") {
dispatch(
fetchBooksData({
name: resultName,
startIndex: resultStartIndex,
category: resultCategory,
sort: resultSort,
})
);
}
function categoryChange() {
setResultCategory(document.querySelector("#category").value);
setResultStartIndex(0);
dispatch(
fetchBooksData({
name: resultName,
startIndex: resultStartIndex,
category: resultCategory,
sort: resultSort,
})
);
}
function sortChange() {
setResultSort(document.querySelector("#sort").value);
setResultStartIndex(0);
dispatch(
fetchBooksData({
name: resultName,
startIndex: resultStartIndex,
category: resultCategory,
sort: resultSort,
})
);
}
function handleSubmit() {
const input = document.querySelector("#form");
setResultName(input.value);
}
function go_back() {
setResultStartIndex(resultStartIndex - 30);
}
function go_forward() {
setResultStartIndex(resultStartIndex + 30);
}
function handleKeyPress(e) {
if (e.charCode == 13) {
e.preventDefault()
const input = document.querySelector("#form");
setResultName(input.value);
}
}
return (
<>
<Head>
<title>Books catalog</title>
</Head>
<div id="page-preloader" className="preloader">
<div className="loader"></div>
</div>
<header className="header">
<Container>
<h1 className="title">Search for books</h1>
<Form>
<Row className="justify-content-center">
<Col xl={6}>
<InputGroup>
<Form.Control
onKeyPress={handleKeyPress}
id="form"
placeholder="Search books"
/>
<Button type="button" onClick={handleSubmit}>
Search
</Button>
</InputGroup>
</Col>
</Row>
<Row className="mt-3 justify-content-center">
<Col xl={3}>
<Form.Select
onChange={categoryChange}
id="category"
aria-label="Default select example"
>
<option value="all">all</option>
<option value="art">art</option>
<option value="biography">biography</option>
<option value="computers">computers</option>
<option value="history">history</option>
<option value="medical">medical</option>
<option value="poetry">poetry</option>
</Form.Select>
</Col>
<Col xl={3}>
<Form.Select
onChange={sortChange}
id="sort"
aria-label="Default select example"
>
<option value="relevance ">relevance </option>
<option value="newest">newest</option>
</Form.Select>
</Col>
</Row>
</Form>
</Container>
</header>
<Container>Всего книг по вашему запросу: {books.totalItems}</Container>
<Container>
<div className="books">
{books.items?.map((book, index) => {
return <BookComponent book={book} key={index} />;
})}
</div>
</Container>
<footer>
{resultStartIndex !== 0 ? (
<Button className="go_back" onClick={go_back}>
go back
</Button>
) : (
<></>
)}
{books.totalItems > resultStartIndex ? (
<Button className="go_forward" onClick={go_forward}>
go forward
</Button>
) : (
<></>
)}
</footer>
</>
);
}
pages/book/[id].js
import React, { useState, useEffect } from "react";
import Link from "next/link";
import { Button, Container, Image, Row, Col } from "react-bootstrap";
import { useSelector, useDispatch } from "react-redux";
import { fetchThisBookData } from "../../slices/thisBookSlice";
import { useRouter } from "next/router";
export default function bookId() {
const router = useRouter();
const book = useSelector((state) => state.thisBook.thisBook);
const error = useSelector((state) => state.thisBook.error);
const dispatch = useDispatch();
useEffect(() => {
dispatch(
fetchThisBookData({
id: router.query.id,
})
);
}, [dispatch, router]);
if (error === "error") {
dispatch(
fetchThisBookData({
id: router.query.id,
})
);
}
console.log(book);
return (
<div>
<Container>
<div id="page-preloader" className="preloader">
<div className="loader"></div>
</div>
<Link href={"/"} className="back">
<Button className="back">Back</Button>
</Link>
<Row className="justify-content-center">
<Col>
<h1 className="this_book__title">{book?.volumeInfo?.title}</h1>
</Col>
</Row>
<Row>
<Col xl={6}>
<strong>Категории:</strong>
{book?.volumeInfo?.categories ? (
<div className="this_book__category">
{book?.volumeInfo?.categories}
</div>
) : (
<div>Нет категорий</div>
)}
<div className="this_book__autors">
<strong>
{book?.volumeInfo?.authors.length === 1 ? (
<>Автор </>
) : (
<>Авторы: </>
)}
</strong>
{book?.volumeInfo?.authors}
</div>
<br />
</Col>
<Col xl={6}>
{book?.volumeInfo?.imageLinks?.extraLarge ? (
<Image
src={book?.volumeInfo?.imageLinks?.extraLarge}
alt="book cover"
className="this_book__img"
/>
) : (
<Image
className="noCover"
src="https://rublevbar.com/files/rublevbar/image/no_product.jpg"
alt="no book cover"
/>
)}
</Col>
</Row>
</Container>
</div>
);
}
slices/booksSlice.js
import { createSlice, createAsyncThunk } from "#reduxjs/toolkit";
const initialState = {
books: [],
status: null,
error: null,
};
export const fetchBooksData = createAsyncThunk(
"books/fetchData",
async function (state) {
const response = await fetch(
`https://www.googleapis.com/books/v1/volumes?q=${state.name}+${state.category}&startIndex=${state.startIndex}&maxResults=30&orderBy=${state.sort}`
);
const data = await response.json();
return data;
}
);
export const booksSlice = createSlice({
name: "books",
initialState,
extraReducers: {
[fetchBooksData.pending]: (state) => {
state.status = "loading";
state.error = null;
const preloader = document.querySelector("#page-preloader");
if (preloader.classList.contains("done")) {
preloader.classList.remove("done");
}
},
[fetchBooksData.fulfilled]: (state, action) => {
state.status = "resolved";
state.error = null;
state.books = action.payload;
const preloader = document.querySelector("#page-preloader");
if (!preloader.classList.contains("done")) {
preloader.classList.add("done");
}
},
[fetchBooksData.rejected]: (state) => {
state.error = "error";
console.log("Error");
},
},
});
export default booksSlice.reducer;
slices/thisBookSlice.js
import { createSlice, createAsyncThunk } from "#reduxjs/toolkit";
const initialState = {
thisBook: [],
status: null,
error: null,
};
export const fetchThisBookData = createAsyncThunk(
"books/fetchThisData",
async function (state) {
const response = await fetch(
`https://www.googleapis.com/books/v1/volumes/${state.id}`
);
const data = await response.json();
return data;
}
);
export const thisBookSlice = createSlice({
name: "book",
initialState,
extraReducers: {
[fetchThisBookData.pending]: (state) => {
state.status = "loading";
state.error = null;
const preloader = document.querySelector("#page-preloader");
if (preloader.classList.contains("done")) {
preloader.classList.remove("done");
}
},
[fetchThisBookData.fulfilled]: (state, action) => {
state.status = "resolved";
state.error = null;
state.thisBook = action.payload;
const preloader = document.querySelector("#page-preloader");
if (!preloader.classList.contains("done")) {
preloader.classList.add("done");
}
},
[fetchThisBookData.rejected]: (state) => {
state.error = "error";
console.log("Error");
},
},
});
export default thisBookSlice.reducer;

How to make Post request with Axios (MERN Stack)

I am new to REACT and the MERN Stack and try to understand everything. But sometimes, it seems that the simplest things do not want to get into my head.
I hope that, one day, I will understand it all. Until then it still seems a long way away. Anyway. I am starting with a simple MERN app. All users should be displayed on the start page. On a separate "page" there should be a create users form. For now, the users are displayed on the home screen but when I switch back from the "create users page" they dissappeared. Furthermore the input form do not work (validation error). When checking get and posts requests from my backend with Thunder Client everthing works, so I suppose, this might be something to do with the frontend. Sorry for my wording. I am a programming newbie.
I hope it is somewhat understandable. What am I doing wrong? I would be so happy, if anyone could help. Thank you!
client/src/App.js
import React from "react";
import { Routes, Route } from "react-router-dom";
import AllUsers from "./pages/AllUsers";
import Navigation from "./components/Navigation";
import CreateUser from "./pages/CreateUser";
import "./App.css";
function App() {
return (
<div className="App">
<Navigation />
<Routes>
<Route path="/" element={<AllUsers />} />
<Route path="create-User" element={<CreateUser />} />
</Routes>
</div>
);
}
export default App;
client/src/components/Navigation.js
import React from "react";
import { Link } from "react-router-dom";
const Navigation = () => {
return (
<header className="bg-background border-t-0 shadow-none">
<nav className="bg-navigation bg-opacity-40 rounded-t-xs flex justify-around h-12 p-3 ">
<Link to="/create-user">Create User</Link>
<Link to="/">
<img id="workshop-icon" src="../assets/home.svg" alt="home button" />
</Link>
</nav>
</header>
);
};
export default Navigation;
client/src/AllUsers.js
import React from "react";
import { useState, useEffect } from "react";
import Axios from "axios";
const AllUsers = () => {
const [listOfUsers, setListOfUsers] = useState([]);
useEffect(() => {
Axios.get("http://localhost:3001/getUsers").then((response) => {
setListOfUsers(response.data);
});
}, []);
return (
<div className="App">
<div className="usersDisplay">
{listOfUsers.map((user) => {
return (
<div key={user._id}>
<h1>Name: {user.name}</h1>
<h1>Age: {user.age}</h1>
<h1>Username: {user.username}</h1>
</div>
);
})}
</div>
</div>
);
};
export default AllUsers;
client/src/createUser.js
import React from "react";
import { useState } from "react";
import Axios from "axios";
const CreateUser = () => {
const [listOfUsers, setListOfUsers] = useState([]);
const [name, setName] = useState("");
const [age, setAge] = useState(0);
const [username, setUsername] = useState("");
Axios.post("http://localhost:3001/createUser", {
name,
age,
username,
}).then((response) => {
setListOfUsers([
...listOfUsers,
{
name,
age,
username,
},
]);
});
return (
<div className="input">
<div>
<input
type="text"
placeholder="Name..."
onChange={(event) => {
setName(event.target.value);
}}
/>
<input
type="number"
placeholder="Age..."
onChange={(event) => {
setAge(event.target.value);
}}
/>
<input
type="text"
placeholder="Username..."
onChange={(event) => {
setUsername(event.target.value);
}}
/>
<button onClick={CreateUser}> Create User </button>
</div>
</div>
);
};
export default CreateUser;

Redirecting/Rendering different component upon validation ionic react

I'm fairly new Ionic React and trying to create an App using Ionic framework. I have a use case where I would like to redirect to another page upon a button press and validation from a function.
Here is the component I am working with
import React, { useState } from 'react';
import {
IonContent,
IonHeader,
IonPage,
IonTitle,
IonToolbar,
IonInput,
IonButton,
IonRow,
IonCol,
useIonViewWillEnter,
useIonViewWillLeave,
IonLabel
} from '#ionic/react';
import './LogIn.css'
import MainMenu from "../MainMenu";
const LogIn: React.FC<{register?: boolean; onClose?: any}> = () => {
const [email, setEmail] = useState<string>();
const [password, setPassword] = useState<string>();
function handleLoginButtonPress() {
if (validateEmail() && password !== undefined && password.trim() !== "") {
// Network call here to check if a valid user
console.log("valid email")
return <MainMenu/>
}
}
function validateEmail () {
if (email !== undefined && email.trim() !== "") {
const regexp = /^(([^<>()[\]\\.,;:\s#"]+(\.[^<>()[\]\\.,;:\s#"]+)*)|(".+"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return regexp.test(email);
}
return false;
}
useIonViewWillEnter(() => {
console.log("Entering LogIn");
});
useIonViewWillLeave(() => {
console.log("Exiting LogIn");
});
return (
<IonPage id="loginIonPage">
<IonHeader>
<IonToolbar color="primary" mode="md">
<IonTitle class="ion-text-center">Login or Register</IonTitle>
</IonToolbar>
</IonHeader>
<IonContent id="loginPage">
<div id="loginDialog">
<form>
<IonLabel>Email</IonLabel>
<IonRow>
<IonCol id="userName">
<IonInput
name="email"
value={email}
onIonChange={e => setEmail(e.detail.value!)}
clearInput
type="email"
placeholder="Email"
class="input"
padding-horizontal
clear-input="true"
required/>
</IonCol>
</IonRow>
<IonLabel>Password</IonLabel>
<IonRow>
<IonCol id="password">
<IonInput
clearInput
name="password"
value={password}
onIonChange={e => setPassword(e.detail.value!)}
type="password"
placeholder="Password"
class="input"
padding-horizontal
clear-input="true"
required/>
</IonCol>
</IonRow>
</form>
</div>
<div id="buttons">
<IonButton
onClick={handleLoginButtonPress}
type="submit"
strong={true}
expand="full"
style={{ margin: 20 }}>
Log in
</IonButton>
<IonButton
routerLink="/registerUser"
type="submit"
strong={true}
expand="full"
style={{ margin: 20 }}>
Register
</IonButton>
</div>
</IonContent>
</IonPage>
);
};
export default LogIn;
How can I redirect to another page from the function handleLoginButtonPress which is invoked upon clicking on Login button. I tried reading through ionic doc but that did not help as it redirects whenever there is button click or click on an IonElement like IonLabel.
Use react-router-dom hooks
https://reacttraining.com/react-router/web/api/Hooks/usehistory
import { useHistory } from "react-router-dom";
const ExampleComponent: React.FC = () => {
const history = useHistory();
const handleLoginButtonPress = () => {
history.push("/main");
};
return <IonButton onClick={handleLoginButtonPress}>Log in</IonButton>;
};
export default ExampleComponent;
Thanks, #MUHAMMAD ILYAS and it would have worked for me. But I managed to leverage the react state as below, I have added as an answer as I could not format the code there,
const ValidateUser : React.FC = () => {
const [login, setLogin] = useState(false);
function isUserLoggedIn() {
return login;
}
return(
<IonReactRouter>
<IonRouterOutlet>
<Route path="/" render={() => isUserLoggedIn()
? <MainMenu/>
: <LogIn setUserLoggedIn={() => {setLogin(true)}}/>} exact={true}/>
</IonRouterOutlet>
</IonReactRouter>
);
};
const LogIn: React.FC<{setUserLoggedIn?: any}> = ({setUserLoggedIn}) => {
.
.
function onLoginButtonPress() {
setUserLoggedIn();
}
}
Thanks

react-semantic-ui-datepickers no form value in redux-form

This issue applied the standard implementation without additional customisations.
The is no value on submit of the form and onChange does not fire with the current value.
<Form onSubmit={handleSubmit(this.onSubmit)}>
<Form.Group>
<Field
component={SemanticDatepicker}
name="working"
dateFormat="DD/MM/YYYY"
label="Date of birth"
placeholder="select your DOB"
size="small"
onChange={(e, value) => {
console.log(e, value);
}}
/>
</Form.Group>
<Form.Field
control={Button}
color="purple"
className="submit-btn"
type="submit"
width={6}
>
Save
</Form.Field>
</Form>
A minimal version can be found here https://github.com/chrishj59/datepickerIssue
I could capture the onChange value by creating a custom component which wrapped the <SemanticDatepicker />. I also added mapStateToProps to log the redux-form values. You can consider this as a starting point and work on this.
//SongList.js
state = {
date: "",
};
render(){
const DatePick = () => {
return (
<SemanticDatepicker
onChange={this.datePickerOnChange}
format="YYYY-MM-DD"
/>
);
};
return (
<Form onSubmit={handleSubmit(this.onSubmit)}>
<Form.Group>
<Field
component={DatePick}
name="working"
dateFormat="DD/MM/YYYY"
label="Date of birth"
placeholder="select your DOB"
size="small"
/>
</Form.Group>
<Form.Field
control={Button}
color="purple"
className="submit-btn"
type="submit"
width={6}
>
Save
</Form.Field>
</Form>
);
}
//App.js
import { connect } from "react-redux";
const App = (props) => {
console.log(props.form);
return (
<div>
{" "}
<SongList />
</div>
);
};
const mapStateToProps = (state) => ({
form: state.form,
});
export default connect(mapStateToProps)(App);
I managed to resolve using semantic-ui-redux-form-fields to wrap the Semantic UI component. This now gives the correct format and value appearing in the validate function and formProps.
import React from "react";
imp ort { fieldEnhance } from "semantic-ui-redux-form-fields";
import { compose } from "redux";
import SemanticDatepicker from "react-semantic-ui-datepickers";
import "react-semantic-ui-datepickers/dist/react-semantic-ui-datepickers.css";
const DatePickerPure = (props) => {
const { currentValue, input, ...rest } = props;
const defaultProps = {
format: "DD/MMM/YYYY",
onChange: (event, data) => input.onChange(data.value),
value: currentValue,
...rest,
};
return <SemanticDatepicker {...props} {...defaultProps} />;
};
export default compose(fieldEnhance)(DatePickerPure);