The above error occurred in the <Provider> component - javascript

can't find way how to resolve this problem.
Errors in browser:
Uncaught Error: Invalid hook call. Hooks can only be called inside
of the body of a function component. This could happen for one of
the following reasons:
You might have mismatching versions of React and the renderer (such as React DOM)
You might be breaking the Rules of Hooks
You might have more than one copy of React in the same app See https://reactjs.org/link/invalid-hook-call for tips about how to
debug and fix this problem.
The above error occurred in the component:
Provider#http://localhost:3000/static/js/bundle.js:49534:15
Consider adding an error boundary to your tree to customize error
handling behavior. Visit https://reactjs.org/link/error-boundaries
to learn more about error boundaries.
INDEX.JS
import React from 'react';
import ReactDOM from 'react-dom';
import Router from './Router';
import { createStore } from 'redux'
import { composeWithDevTools } from 'redux-devtools-extension'
import { Provider } from 'react-redux'
import rootReducer from './Redux/Reducers/index.js'
const store = createStore( rootReducer, composeWithDevTools() )
ReactDOM.render(
<Provider store={ store }>
<Router />
</Provider >,
document.getElementById( 'root' ) );
Reducers/index.js
import loginPageReducer from './LoginPage.js'
import { combineReducers } from 'redux'
const rootReducer = combineReducers( {
loginPageReducer
} )
export default rootReducer
Reducers/LoginPage.js
const INIT_STATE = {
view: 'login',
msg: '',
loader: false,
}
const loginPageReducer = ( state = INIT_STATE, action ) =>
{
switch ( action.type )
{
case "LOADER_OFF":
return state.loader = false
case "LOADER_ON":
return state.loader = true
case "MSG_SET":
return state.msg = action.msg
case "MSG_CLEAR":
return state.msg = ''
case "VIEW_CHANGE":
return state.view = action.view
default:
return state;
}
}
export default loginPageReducer
loginPage component
import React, { useState } from 'react'
import '../Styles/loginPage.scss'
import axios from 'axios'
import { useDispatch, useSelector } from 'react-redux'
import loginPageActions from '../Redux/actions/LoginPage'
export default function LoginPage ()
{
const { msg_clear, msg_set, loader_off, loader_on, view_change } = loginPageActions
const msg = useSelector( state => state.LoginPageReducer.msg )
const view = useSelector( state => state.LoginPageReducer.view )
const loader = useSelector( state => state.LoginPageReducer.loader )
const dispatch = useDispatch()
const [inputs, setInputs] = useState( {
username: '',
password: '',
password2: '',
email: ''
} )
const handleInputs = function ( e )
{
const { name, value } = e.target
setInputs( { ...inputs, [name]: value } )
}
const handleSubmit = async ( e ) =>
{
try
{
e.preventDefault();
dispatch( msg_clear() )
dispatch( loader_on() )
if ( view === login)
{
// logowanie
const query = await axios( {
method: 'post',
url: '/api/users/login',
data: {
username: inputs.username,
password: inputs.password
}
} )
const token = query.data.token
localStorage.setItem( "token", token );
return window.location.href = "/kalkulator"
}
else
{
//rejestracja
const query = await axios( {
method: 'post',
url: '/api/users/register',
data: {
username: inputs.username,
password: inputs.password,
password2: inputs.password2,
email: inputs.email
}
} )
if ( query.status === 200 )
{
dispatch( msg_set( 'Zarejestrowano, możesz się zalogować' ) )
dispatch( view_change( true ) )
}
}
}
catch ( err )
{
if ( err ) return dispatch( msg_set( err.response.data.msg ) )
}
finally
{
dispatch( loader_off() )
}
}
/////////////
/// Renderowanie widoku
/////////////
return (
<main>
<div id="MainContainerStyle">
<span id="thatWhitePartOnBottom"></span>
<header>
<h1 id="HeaderH1" >Kalkulator mas</h1>
</header>
<button className="Buttons" onClick={ () => dispatch( view_change( !view ) ) }>
{ view ?
`Already have account? Click to log in!`
:
`Doesn't have account? Click me if you want to register new one` }
</button>
<form onSubmit={ handleSubmit } id="Form">
<input type="text"
value={ inputs.username }
placeholder={ view ? 'username' : 'Login or E-mail' }
name="username" required onChange={ handleInputs }
/>
{ view ?
<input type="email"
placeholder="email"
name="email"
value={ inputs.email }
required
onChange={ handleInputs } />
:
null
}
<input type="password"
value={ inputs.password }
placeholder="Password:"
name="password"
required
onChange={ handleInputs }
/>
{ view ?
<input type="password"
value={ inputs.password2 }
placeholder="Password again:"
name="password2"
required
onChange={ handleInputs } />
:
null
}
<input type="submit" className="Buttons" />
{ loader ? <span className="loader"></span> : null }
{ msg !== '' ? <p className="msg">{ msg }</p> : null }
</form>
</div>
</main>
)
}
Router
import { BrowserRouter, Routes, Route } from "react-router-dom";
import './Styles/global.scss'
import LoginPage from "./Pages/LoginPage";
import Kalkulator from "./Pages/Kalkulator";
function App ()
{
return (
<>
<BrowserRouter>
<Routes>
<Route path="/" element={ <LoginPage /> } />
<Route path="/kalkulator" element={ <Kalkulator /> } />
</Routes>
</BrowserRouter>
</>
)
}
export default App;

might be this problem: https://reactjs.org/warnings/invalid-hook-call-warning.html#duplicate-react
Assuming myapp and mylib are sibling folders, one possible fix is to run npm link ../myapp/node_modules/react from mylib. This should make the library use the application’s React copy.
..or maybe "react-redux" is not installed, check package.json

Related

this.props.history.push() not working in ReactJS

Trying my hands at ReactJS fetch() examples. As mentioned this.props.history.push() not working, it is not giving an error, but it is simply not redirecting. Tried to read other answers to this question on StackOverflow, but many of them are either too complex(some ppl showing off) or some not very clear.
index.js:
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import { BrowserRouter as Router, NavLink, Switch, Route, useHistory } from "react-router-dom";
import reportWebVitals from "./reportWebVitals";
ReactDOM.render(
<React.StrictMode>
<Router>
<App />
</Router>
</React.StrictMode>,
document.getElementById("root")
);
App.js :
import "./App.css";
import React from "react";
import { BrowserRouter as Router, NavLink, Switch, Route, useHistory } from "react-router-dom";
import RouterPage1 from "./RouterPage1";
import RouterPage2 from "./RouterPage2";
export default function App(props) {
let history = useHistory();
return (
<div>
<nav>
<ol>
<li>
<NavLink to="/RouterPage1">RouterPage1</NavLink>
</li>
<li>
<NavLink to="/RouterPage2">RouterPage2</NavLink>
</li>
<li>
<NavLink to="/RouterPageBoth">RouterPageBoth</NavLink>
</li>
</ol>
</nav>
<Switch>
<Route exact path="/RouterPage1">
<RouterPage1 history={history} />
</Route>
<Route exact path="/RouterPage2">
<RouterPage2 history={history} />
</Route>
</Switch>
</div>
);
}
RouterPage2.js(only the necessary code pasted, not the entire component for brevity):
addastakeholder = () => {
let newstakeholder = JSON.stringify(this.state.newstakeholder);
fetch("http://localhost:8080/OneToOneMappingPractice/add", {
method: "POST",
headers: { "Content-type": "application/json" },
body: newstakeholder,
}).then((r) => {
if (r.ok) {
//window.location.href = "/RouterPage2";
this.setState({ newstakeholder: { name: "", address: { house_number: "", streetName: "" } } });
this.props.history.push("/RouterPage2");
}
});
};
when I use the addastakeholder(), it is POSTing successfully, data is being entered in the DB, but it is not giving me an error and not redirecting. In the App.js, if I use the props and not useHistory(), it gives me "this.props.history not defined" error, even though I have enclosed App component in BrowserRouter component in the index.js.
Why is it so?
Secondly, if I use the commented out window.location.href = "/RouterPage2", it works(POSTing is successfull), but I am not able to see POST log in Development Tools:Network tab(Firefox). Why is this so?
Tried this.context.history.push("/RouterPage2"), does not work, same undefined error.
P.S.:edit 1:
the full RouterPage2.js(Kindly ignore result variable and the related code. Consider only result2.):
import React from "react";
export default class RouterPage2 extends React.Component {
constructor(props) {
super(props);
this.state = {
stakeholders: [],
errorString: "",
newstakeholder: { name: "", address: { house_number: "", streetName: "" } },
};
}
componentDidMount() {
fetch("http://localhost:8080/OneToOneMappingPractice/getAll")
.catch((error) => this.setState({ errorString: error }))
.then((result) => result.json())
.then((result) => this.setState({ stakeholders: result }));
}
addastakeholder = () => {
let newstakeholder = JSON.stringify(this.state.newstakeholder);
fetch("http://localhost:8080/OneToOneMappingPractice/add", {
method: "POST",
headers: { "Content-type": "application/json" },
body: newstakeholder,
}).then((r) => {
if (r.ok) {
//window.location.href = "/RouterPage2";
this.setState({ newstakeholder: { name: "", address: { house_number: "", streetName: "" } } });
this.props.history.push("/RouterPage2");
}
});
};
render() {
let result, result2;
let error = false;
if (this.state.stakeholders.length > 0)
result = (
<ol>
{this.state.stakeholders.map((stakeholder) => (
<li key={stakeholder.stakeholder_id}>
{stakeholder.stakeholder_name} | {stakeholder.stakeholder_type} |
{stakeholder.stakeholder_email_id} | {stakeholder.stakeholder_contactno} |
{stakeholder.stakeholder_bankname} | {stakeholder.stakeholder_bankBranch} |
{stakeholder.stakeholder_IFSC} | {stakeholder.stakeholder_AccNo} |
{stakeholder.stakeholder_AccType} | {stakeholder.stakeholder_PAN}
</li>
))}
</ol>
);
else result = false;
if (this.state.stakeholders.length > 0)
result2 = (
<ol>
{this.state.stakeholders.map((stakeholder) => (
<li key={stakeholder.id}>
{stakeholder.name}|{stakeholder.address.house_number}|{stakeholder.address.streetName}
</li>
))}
</ol>
);
else result2 = false;
if (this.state.errorString !== "undefined") error = this.state.errorString;
let blank = false;
if (result == false) blank = <h5>There are no records to display.</h5>;
return (
<div>
<h1>Stakeholder details :</h1>
{result2}
{error}
{blank}
<form>
Name :{" "}
<input
type="text"
placeholder="Name"
value={this.state.newstakeholder.name}
onChange={(e) => {
this.setState({ newstakeholder: { ...this.state.newstakeholder, name: e.target.value } });
}}
/>
<br></br>
StreetName :{" "}
<input
type="text"
placeholder="StreetName"
value={this.state.newstakeholder.address.streetName}
onChange={(e) => {
this.setState({
newstakeholder: {
...this.state.newstakeholder,
address: { ...this.state.newstakeholder.address, streetName: e.target.value },
},
});
}}
/>
<br></br>
HouseNumber :{" "}
<input
type="text"
placeholder="HouseNumber(Digits Only)"
value={this.state.newstakeholder.address.house_number}
onChange={(e) => {
this.setState({
newstakeholder: {
...this.state.newstakeholder,
address: { ...this.state.newstakeholder.address, house_number: e.target.value },
},
});
}}
/>
<br></br>
<button type="button" onClick={this.addastakeholder}>
Add Stakeholder
</button>
</form>
</div>
);
}
}
Tried everything. As suggested by Kurtis above in the comments, for troubleshooting purposes, did : console.log(this.props);
Got following response :
as you can see, there is the push function with different signature, hence tried : this.props.history.push("/RouterPage2", ""). Again did not work.
Hence, thought of trying the go(). And it worked.
this.props.history.go("/RouterPage2");
working now perfectly.

React Too many re-renders

I am following the serverless-stack.com tutorial. But I am stuck after creating the login button.
I keep getting the error:
Uncaught Error: Too many re-renders. React limits the number of renders to prevent an infinite loop.
I don't know what is causing the render so many times.
I combined my LoaderButton instead of importing to make it simpler.
import React, { useState } from "react";
import { Auth } from "aws-amplify";
import { useHistory } from "react-router-dom";
import { FormGroup, FormControl, ControlLabel } from "react-bootstrap";
import { useFormFields } from "../libs/hooksLib";
import { onError } from "../libs/errorLib";
import "../css/index.css";
const LoaderButton = (
isLoading,
className = "",
disabled = false,
...props ) => {
return(
<Button
className={`LoaderButton ${className}`}
disabled={disabled || isLoading}
{...props}
>
{isLoading && <Glyphicon glyph="refresh" className="spinning" />}
{props.children}
</Button>
)
};
export default function Login() {
let history = useHistory();
const [isLoading, setIsLoading] = useState(false);
const [fields, handleFieldChange] = useFormFields({
email: "",
password: ""
});
function validateForm() {
return fields.email.length > 0 && fields.password.length > 0;
}
async function handleSubmit(event) {
event.preventDefault();
setIsLoading(true);
try {
await Auth.signIn(fields.email, fields.password);
userHasAuthenticated(true);
console.log(history);
//history.push("/");
} catch (e) {
onError(e);
setIsLoading(false);
}
}
return (
<div className="Login">
<form onSubmit={ () => { handleSubmit() } }>
<FormGroup controlId="email" bsSize="large">
<ControlLabel>Email</ControlLabel>
<FormControl
autoFocus
type="email"
value={fields.email}
onChange={ () => { handleFieldChange() } }
/>
</FormGroup>
<FormGroup controlId="password" bsSize="large">
<ControlLabel>Password</ControlLabel>
<FormControl
type="password"
value={fields.password}
onChange={ () => { handleFieldChange() } }
/>
</FormGroup>
<LoaderButton
block
type="submit"
bsSize="large"
isLoading={ () => { isLoading() } }
disabled={() => { !validateForm() }}
>
Login
</LoaderButton>
</form>
</div>
);
}
hooksLib.js / useFormFields
import { useState } from 'react'
const useFormFields = (initalState) => {
const [fields, setValues] = useState(initalState)
return [
fields,
setValues({
...fields,
[event.target.id]: event.target.value
})
]
}
export { useFormFields }
Your custom hook should look like this if you want to accept the event value:
const useFormFields = (initalState) => {
const [fields, setValues] = useState(initalState)
return [
fields,
(event) => setValues({
...fields,
[event.target.id]: event.target.value
})
]
}
Since that parameter is actually a callback that should occur.
Also, your LoadingButton implementation needs to change to this:
<LoaderButton
block
type="submit"
bsSize="large"
isLoading={isLoading} // This is a boolean value, not a function
disabled={() => !validateForm()}
>...</LoaderButton>

React Context API does not update after calling dispatch

I have a login component that stores the user information in the global state after a successful login. The login component is pretty straight forward. It contains a form with a handleSubmit event that calls an endpoint. Based on the result of that endpoint an action is taken. The login component looks like this.
import React, { Component } from 'react';
import { StateContext } from '../state';
import { login } from '../repositories/authenticationRepository';
class Login extends Component {
static contextType = StateContext;
constructor(props) {
super(props);
this.state = {
email: '',
password: '',
message: '',
};
}
handleChange = (event) => {
const { name, value } = event.target;
this.setState({ [name]: value });
}
handleSubmit = async (event) => {
event.preventDefault();
const [{}, dispatch] = this.context;
const { history } = this.props;
const { email, password } = this.state;
const isLoggedInResponse = await login({ email, password });
if (isLoggedInResponse.data.type === 'error') {
this.setState({ message: isLoggedInResponse.data.message });
return;
}
dispatch({ type: 'storeUserInformation', userInformation: isLoggedInResponse.data.message });
history.push('/');
}
render() {
const { email, password, message } = this.state;
return (
<div className="login-wrapper">
<form onSubmit={this.handleSubmit}>
<label htmlFor="email">
Email:
<input autoComplete="off" name="email" type="text" value={email} onChange={this.handleChange} />
</label>
<label htmlFor="password">
Password:
<input autoComplete="off" id="password" name="password" type="password" value={password} onChange={this.handleChange} />
</label>
{message.length > 0 && <span className="text-danger error">{message}</span> }
<input className="btn btn-secondary" type="submit" value="Submit" />
</form>
</div>
);
}
}
export default Login;
When testing it myself I can see the user information being set in the ReactJS devtools. Of course I want to test this automatically using a unit test, so I wrote the following.
jest.mock('../../repositories/authenticationRepository');
import React from 'react';
import { mount } from 'enzyme';
import Login from '../../pages/Login';
import { StateProvider } from '../../state';
import { login } from '../../repositories/authenticationRepository';
import { act } from 'react-dom/test-utils';
import history from '../../sitehistory';
import { BrowserRouter as Router } from 'react-router-dom';
import { reducer } from '../../reducer';
it('Saves the user information in the store on a succesfull login', async () => {
login.mockReturnValue(({ data: { type: 'success', message: 'Message should be stored' }}));
let initialStateMock = {}
const wrapper = mount(
<StateProvider initialState={initialStateMock} reducer={reducer}>
<Router>
<Login history={history} />
</Router>
</StateProvider>
);
let emailEvent = { target: { name: 'email', value: 'test#example.com'} }
let passwordEvent = { target: { name: 'password', value: 'password'} }
wrapper.find('input').first().simulate('change', emailEvent);
wrapper.find('input').at(1).simulate('change', passwordEvent);
const submitEvent = { preventDefault: jest.fn() }
await act(async () => {
wrapper.find('form').first().simulate('submit', submitEvent);
});
act(() => {
wrapper.update();
});
console.log(initialStateMock); // expected { userInformation: 'Message should be stored' } but got {}
});
I expect the initialStatemock to have the value of { userInformation: 'Message should be stored' }. However it still has the initial value of {}. I tried wrapper.update() to force a refresh but to no avail. What am I overlooking?

How to fix problems with add-comment and remove-comment in react-redux app

I'm writting react-redux comment's widget.Faced the following problem. When I click on the add comments button, no addition occurs, and when I click on delete a comment, he writes that map is not a function, although I pass an array of comments. Can you explain where i made a mistake
actions/index.js
let nextCommentId = 0;
export const ADD_COMMENT = 'ADD_COMMENT';
export const REMOVE_COMMENT = 'REMOVE_COMMENT';
export const addComment = (comment) => {
return {
type: ADD_COMMENT,
id: nextCommentId++,
payload: comment
}
}
export const removeComment = (id) => {
return {
type: REMOVE_COMMENT,
id
}
}
components/add-comment.js
import React, { Component, useState } from 'react';
import { addComment } from '../actions/index.js'
class AddComment extends React.Component {
constructor(props) {
super(props);
this.state = {
date: new Date(),
text: '',
name: ''
};
}
render() {
let comment = {
name: this.state.name,
text: this.state.text,
date: this.state.date
}
return (
<div>
<form>
<label htmlFor="username">Введите ваше имя:</label> <br />
<input
type="text"
id="username"
value={this.state.name}
onChange={ev => {
this.setState({ name: ev.target.value });
}}
/> <br /><br />
<label htmlFor="usercomment">Введите ваш комментарий:</label> <br />
<textarea
id="usercomment"
rows="10"
cols="40"
value={this.state.text}
onChange={ev => {
this.setState({ text: ev.target.value });
}}
></textarea> <br />
</form>
<button
className="btn"
onClick={ev => {
addComment(comment);
}}
>
Добавить комментарий
</button>
</div>
);
}
}
export default AddComment;
components/comment-list.js
import React from 'react';
import AddComment from './add-comments.js';
import { removeComment } from '../actions/index';
const CommentList = ({ comments , removeComment }) => {
return (
<ul>
{
comments.map((comment, index) => {
debugger;
return (
<li key={index}>
<b>
{comment.name + comment.date}
</b> <button
className="btn-remove"
onClick={ev => {
if (comments.length === 0) {
return comments
} else {
removeComment(index)
}
}}
>
Удалить комментарий
</button><br />
{comment.text}
</li>
)
})
}
</ul>
)
}
export default CommentList;
containers/app.js
import React from 'react';
import { connect } from 'react-redux';
import CommentList from '../components/comment-list';
import AddComment from '../components/add-comments';
import { addComment,removeComment } from '../actions/index';
let App = ({ comments, addComment, removeComment }) => {
return (
<div>
<CommentList comments={comments} removeComment={removeComment} />
<AddComment addComment={addComment}/>
</div>
)
}
const mapStateToProps = (state) => {
return {
comments: state.comments
}
}
const mapDispatchToProps = (dispatch) => {
debugger;
return {
addComment: (comment) => dispatch(addComment(comment)),
removeComment: (id) => dispatch(removeComment(id))
}
}
App = connect(
mapStateToProps,
mapDispatchToProps
)(App);
export default App;
reducers/index.js
import { ADD_COMMENT, REMOVE_COMMENT } from '../actions/index.js'
const comments = (state = [], action) => {
switch (action.type) {
case ADD_COMMENT:
return [
...state,
action.payload
]
case REMOVE_COMMENT:
return state.comments.filter((comment, id) => id !== action.id);
default:
return state
}
}
export default comments;
src/index.js
import React, {Component} from 'react';
import { render } from 'react-dom';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import App from './containers/app.js';
import { createStore } from 'redux';
import comments from './reducers/index.js';
export const initialState = {
comments: [
{name: 'John', text: 'good', date: '24 октября 17-56'}
]
};
]
const store = createStore( comments, initialState);
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.querySelector('#app')
);
you missed the this.props in onClick={addComment} in components/add-comment.js
try like this
components/add-comment.js
...
<button
className="btn"
onClick={ev => {
this.props.addComment(comment);
}}
>
Добавить комментарий
</button>
...
You mapped dispatch to your action, but then didn't use it, you re-imported the action. Use the action from props instead. If it is not bound to dispatch it will do nothing.

_this2.props.signup is not a function in React Redux app

Please note that I've already checked answers in this question and nothing seems to work.
I'm using this repo as a boilerplate. Instead of firebase database, I'm trying to send username and email with the firebase auth userid , to the node server. I created an action creator signup to handle this.
This is signup.js action creator
import * as types from '../constants/action_types';
import axios from 'axios';
export const signup = (user) => {
console.log(user);
return async dispatch => {
try {
const response = await axios.get('http://localhost:5000/api/user/register', user)
const data = await {response};
dispatch({
type : types.SIGN_UP,
payload : data.fromback
})
} catch (error) {
console.lot(error)
}
}
}
Then I've connected it with the component with mapDispatchToProps., So,under the SignUpPage component, React dev tools shows signup as a function. But when it get triggers, it gives an error saying _this2.props.signup is not a function Why's that ?
This is my SignUpPage component
import React, { Component } from 'react';
import {
Link,
withRouter,
} from 'react-router-dom';
import { auth } from '../../firebase';
import * as routes from '../../constants/routes';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import {signup} from './../../actions/signup';
const SignUpPage = ({ history }) =>
<div>
<h1>SignUp</h1>
<SignUpForm history={history} />
</div>
const updateByPropertyName = (propertyName, value) => () => ({
[propertyName]: value,
});
const INITIAL_STATE = {
username: '',
email: '',
passwordOne: '',
passwordTwo: '',
error: null,
};
class SignUpForm extends Component {
constructor(props) {
super(props);
this.state = { ...INITIAL_STATE };
}
onSubmit = (event) => {
const {
username,
email,
passwordOne,
} = this.state;
const {
history,
} = this.props;
auth.doCreateUserWithEmailAndPassword(email, passwordOne)
.then(authUser => {
const userid = authUser.user.uid;
const user = { email, userid };
this.props.signup(user);
})
.catch(error => {
this.setState(updateByPropertyName('error', error));
});
event.preventDefault();
}
render() {
const {
username,
email,
passwordOne,
passwordTwo,
error,
} = this.state;
const isInvalid =
passwordOne !== passwordTwo ||
passwordOne === '' ||
username === '' ||
email === '';
return (
<form onSubmit={this.onSubmit}>
<input
value={username}
onChange={event => this.setState(updateByPropertyName('username', event.target.value))}
type="text"
placeholder="Full Name"
/>
<input
value={email}
onChange={event => this.setState(updateByPropertyName('email', event.target.value))}
type="text"
placeholder="Email Address"
/>
<input
value={passwordOne}
onChange={event => this.setState(updateByPropertyName('passwordOne', event.target.value))}
type="password"
placeholder="Password"
/>
<input
value={passwordTwo}
onChange={event => this.setState(updateByPropertyName('passwordTwo', event.target.value))}
type="password"
placeholder="Confirm Password"
/>
<button disabled={isInvalid} type="submit">
Sign Up
</button>
{ error && <p>{error.message}</p> }
</form>
);
}
}
const SignUpLink = () =>
<p>
Don't have an account?
{' '}
<Link to={routes.SIGN_UP}>Sign Up</Link>
</p>
const mapDispatchToProps = dispatch => bindActionCreators({ signup }, dispatch)
export default connect(null, mapDispatchToProps)(withRouter(SignUpPage));
export {
SignUpForm,
SignUpLink,
};
Its not a prop,
you've imported it as a function,
you can directly use it as function like this
import {signup} from './../../actions/signup';
.....
auth.doCreateUserWithEmailAndPassword(email, passwordOne)
.then(authUser => {
const userid = authUser.user.uid;
const user = { email, userid };
signup(user);
})
.catch(error => {
this.setState(updateByPropertyName('error', error));
});

Categories

Resources