Push not working
tonybrbtravel opened this issue · 6 comments
The app is wired up such that:
-> user lands on Sign-up page
-> call is made to action, picked up by the sign-up saga.
-> The push is never made.
I'm sure I've wired something up incorrectly, but have spent a day looking at it.
Your help is appreciated.
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { ConnectedRouter } from 'connected-react-router'
import './index.css';
import App from './App';
import store, {history} from './app/store';
import { Provider } from 'react-redux';
import * as serviceWorker from './serviceWorker';
ReactDOM.render(
<Provider store={store}>
<ConnectedRouter history={history}>
<App />
</ConnectedRouter>
</Provider>
document.getElementById('root')
);
app/store.js
import { configureStore, getDefaultMiddleware } from '@reduxjs/toolkit';
import { createBrowserHistory } from 'history'
import createSagaMiddleware from "redux-saga";
import createRootReducer from './reducers'
import rootSaga from './saga'
export const history = createBrowserHistory();
let sagaMiddleware = createSagaMiddleware();
const middleware = [...getDefaultMiddleware({ thunk: false }), sagaMiddleware];
export default configureStore({
reducer: createRootReducer(history),
middleware
});
sagaMiddleware.run(rootSaga);
App.js
import React from 'react';
import logo from './logo.svg';
import { Counter } from './features/counter/Counter';
import { SignUp } from './features/sign-up/Signup';
import './App.css';
import Amplify, { Auth } from 'aws-amplify';
import routes from './routes'
function App() {
return (
<div className="App">
{ routes }
</div>
);
}
export default App;
routes.js
import React from 'react'
import { Route, Switch } from 'react-router-dom'
import {SignUp} from '../features/sign-up/Signup'
import {VerifySignUp} from '../features/verify-signup/VerifySignUp'
const routes = (
<Switch>
<Route exact path="/" component={SignUp} />
<Route exact path="/verify-sign-up" component={VerifySignUp} />
</Switch>
)
export default routes
sign-ip\saga.js
import {
take,
call,
all,
put,
cancel,
select,
takeLatest,
} from 'redux-saga/effects';
import { push } from 'connected-react-router';
import store, {history} from '../../app/store';
import { Auth } from 'aws-amplify';
import {signUpFormUpdate, selectSignUpForm, signUpErrorUpdate} from './signupSlice';
export function* signUp() {
try {
const signUpForm = yield select(selectSignUpForm());
const result = yield call([Auth, Auth.signUp], {
username: signUpForm.email,
password: signUpForm.password,
attributes: {
...(signUpForm.preferred_name && {
preferred_username: signUpForm.preferred_name,
}),
email: signUpForm.email,
},
validationData: [],
});
yield put(push('/verify-sign-up'));
} catch (err) {
console.log(err);
yield put(signUpErrorUpdate(err));
}
}
export function* signUpwatcher() {
yield takeLatest(signUpFormUpdate().type, signUp)
}
Singup.js
import React, { useState, useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import styled from 'styled-components';
import { Link } from 'react-router-dom';
import {H1} from '../../components/H1';
import {Input} from '../../components/Input';
import {Spacer} from '../../components/Spacer';
import {SubmitButton} from '../../components/SubmitButton';
import {Checkbox} from '../../components/Checkbox';
import Colors from '../../themes/Colors';
import Metrics from '../../themes/Metrics';
import { fadeIn } from '../../themes/animations';
import {signUpFormUpdate} from './signupSlice';
import { push } from 'connected-react-router';
import {history} from '../../app/store';
const Form = styled.form`
`;
const FlexWrapper = styled.div`
display: flex;
flex-direction: column;
min-height: 100vh;
@media screen and (min-width: 720px) {
flex-direction: row;
height: 100vh;
}
`;
const SubTextc = styled.ul`
text-align: left;
font-size: 14px;
margin: 0;
padding: 0;
opacity: 0.8;
list-style-type: none;
margin: 0;
padding: 0;
li {
display: inline-block;
margin-right: 20px;
}
@media screen and (min-width: 720px) {
font-size: 16px;
}
`;
const H1c = styled(H1)`
text-align: left;
padding: 0;
font-size: 24px;
letter-spacing: -0.86px;
margin-bottom: 16px;
@media screen and (min-width: 640px) {
font-size: 32px;
}
`;
const ErrorBox = styled.div`
max-width: 860px;
padding: 12px;
border-radius: 6px;
background-color: white;
box-shadow: 0px 2px 12px ${Colors.lightShadow};
margin: 0 auto 12px auto;
animation: ${fadeIn} 0.5s ease-in-out backwards;
strong {
color: ${Colors.red};
}
`;
const FormWrapper = styled.div`
padding: 30px 20px 0px 20px;
width: 100%;
@media screen and (min-width: 600px) {
padding: 30px 60px;
max-width: 800px;
}
`;
const LeftPanel = styled.div`
height: 100%;
width: 100%;
@media screen and (min-width: 720px) {
width: 50%;
max-width: 480px;
}
`;
const RightPanel = styled.div`
display: flex;
flex-grow: 1;
overflow: hidden;
overflow-y: scroll;
align-items: center;
`;
const LinkS = styled(Link)`
color: ${Colors.blue};
`;
const Label = styled.label`
display: flex;
align-items: center;
font-size: 14px;
color: #909090;
margin-bottom: 30px;
a {
color: ${Colors.red};
}
`;
export const SignUp = () => {
const dispatch = useDispatch();
const signUpForm = useSelector(state => state.signup.signUpForm)
const error = useSelector(state => state.signup.signUpError)
let[checked, updateChecked] = useState(false)
const[form, updateForm] = useState(null)
const onChange = (type, evt) => {
const newForm = Object.assign({}, form)
newForm[type] = evt.target.value
updateForm(newForm)
}
const handleCheckboxChange = () => {
checked == false ? checked = true : checked = false
}
const onSubmit = (evt) => {
evt.preventDefault();
dispatch(signUpFormUpdate(form))
}
let PreferredName = <Input
name="preferredName"
placeholder="First name / Nickname"
value={form ? form.preferredName : ''}
onChange={(evt) => onChange('preferredName', evt)}
error={
error && error.preferred_name ? error.preferred_name : null
}
blue
/>
let Email = <Input
name="email"
placeholder="Email"
type="email"
value={form ? form.email : ''}
onChange={(evt) => onChange('email', evt)}
error={error && error.email ? error.email : null}
blue
/>
let Password = <Input
name="password"
placeholder="Password"
type="password"
value={form ? form.password : ''}
onChange={(evt) => onChange('password', evt)}
error={error && error.password ? error.password : null}
blue
/>
let GoButton = <SubmitButton value="Create your free account" blue />
let TandC = <Label>
<Checkbox
checked={checked}
onChange={handleCheckboxChange}
/>
<span>I have read and accept the <Link to="/terms-and-conditions" target="_blank">terms and conditions</Link> and <Link to="/privacy-policy" target="_blank">privacy policy</Link></span>
</Label>
return (
<FlexWrapper>
<LeftPanel>
</LeftPanel>
<RightPanel>
<FormWrapper>
<H1c>Sign up to build your profile</H1c>
<SubTextc>
<li>✓ Build your bucketlist</li>
<li>✓ Select your airports</li>
<li>✓ Choose your plan</li>
</SubTextc>
<Spacer height={Metrics.smallSpacer} />
<Form onSubmit={onSubmit}>
{PreferredName}
{Email}
{Password}
{TandC}
{GoButton}
{error && error && (
<ErrorBox>
<strong>Error:</strong> {error.message || error}
</ErrorBox>
)}
<Spacer height={Metrics.tinySpacer} />
<p
style={{
margin: '20px 0',
fontSize: '18px',
textAlign: 'center',
}}
>
Already have an account? <LinkS to="/sign-in">Sign in</LinkS>
</p>
</Form>
</FormWrapper>
</RightPanel>
</FlexWrapper>
);
}
@tonybrbtravel There is no point on adding these kind of issues here about push. It does not work, and never worked and probably never will. There are hundreds of complains about the same thing all the way back to 2017.
Is quite sad that all of these libraries that do amazing, awesome things, and cannot do the most basic functionality of the internet... redirecting from one url to another. It's quite impressive... or sad.
@tonybrbtravel There is no point on adding these kind of issues here about push. It does not work, and never worked and probably never will. There are hundreds of complains about the same thing all the way back to 2017.
Is quite sad that all of these libraries that do amazing, awesome things, and cannot do the most basic functionality of the internet... redirecting from one url to another. It's quite impressive... or sad.
eh…but why it doesnt work and how to solve it
@Narven @lightyisu This works. You just have to make sure that you do not create your middleware and pass in the history api before calling createRootReducer
function. If you try to create your middleware with routerMiddleware(history)
too early , history
will be passed in as undefined
. Follow the README.md as it explains the exact execution order.
@Narven @lightyisu This works. You just have to make sure that you do not create your middleware and pass in the history api before calling
createRootReducer
function. If you try to create your middleware withrouterMiddleware(history)
too early ,history
will be passed in asundefined
. Follow the README.md as it explains the exact execution order.
Thank u so much for ur help,I will try it😘
After many hours, I have this working.
import { configureStore, getDefaultMiddleware } from '@reduxjs/toolkit';
import { createBrowserHistory } from 'history'
import createSagaMiddleware from "redux-saga";
import { routerMiddleware } from 'connected-react-router'
import { applyMiddleware, compose } from 'redux'
import { persistStore, persistReducer } from 'redux-persist'
import storage from 'redux-persist/lib/storage' // defaults to localStorage for web
import createRootReducer from './reducers'
import rootSaga from './saga'
export const history = createBrowserHistory();
const persistConfig = {
key: 'root',
storage,
}
const rootReducer = createRootReducer(history);
const persistedReducer = persistReducer(persistConfig, rootReducer)
let sagaMiddleware = createSagaMiddleware();
const middleware = [...getDefaultMiddleware({ thunk: false }), sagaMiddleware, routerMiddleware(history)];
export default configureStore({
reducer: persistedReducer,
middleware
});
sagaMiddleware.run(rootSaga);
import React from 'react';
import ReactDOM from 'react-dom';
import { PersistGate } from 'redux-persist/integration/react'
import { persistStore, persistReducer } from 'redux-persist'
import { ConnectedRouter } from 'connected-react-router'
import {
BrowserRouter as Router,
Switch,
Route,
Link
} from "react-router-dom";
import './index.css';
import App from './App';
import store, {history} from './app/store';
import { Provider } from 'react-redux';
import * as serviceWorker from './serviceWorker';
let persistor = persistStore(store)
ReactDOM.render(
<React.StrictMode>
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<ConnectedRouter history={history}>
<App />
</ConnectedRouter>
</PersistGate>
</Provider>
</React.StrictMode>,
document.getElementById('root')
);
// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();
import React from 'react'
import { Route, Switch } from 'react-router-dom'
import {SignUp} from '../features/sign-up/Signup'
import {SocialSignUp} from '../features/social-sign-up/SocialSignUp'
import {Dashboard} from '../features/dashboard/Dashboard'
import TermsAndConditions from '../features/t-and-c/Terms.js'
const routes = (
<Switch>
<Route exact path="/" component={Dashboard} />
<Route exact path="/email-signup" component={SignUp} />
<Route exact path="/social-signup" component={SocialSignUp} />
<Route exact path="/terms-and-conditions" component={TermsAndConditions} />
</Switch>
)
export default routes