React Router: How to keep logged in data (props) when re-routing
I'm creating a React Router app and I'm learning authentication. Here are some parts:
Login component (login.jsx)
- authenticates user's credential on the back end
- sets the authentication token in local storage
- return's the user's data
- sets state with the data
- passes state to Admin component
Admin component (admin.jsx)
- protected by a private route (see privateroute.jsx)
- basically a container component
- passes user's data to and renders other components that display/edit the data
Authentication Button on the nav bar (authbutton.jsx)
- checks if user is logged in and renders "login" or "logout" button
- if logged in, also renders "my posts" button that routes to Admin
All works well from Login to Admin. My problem is that when I click away from the Admin page (like the home page) and then click on "my posts" button, it reroutes to Admin and knows I'm logged in, but the user's data is no longer available. Before, coming from the login component, the user's data was in this.props.location.state.me
.
I'm stuck because I'm trying to route to Admin from two different components and I've never done that before. Furthermore, I feel like there's a solution in the authentication setup that I'm missing.
Other ideas:
Should I conditionally set state in Admin when the user's data is passed?
Should I store the data in local storage in the browser like I'm doing with the authentication token?
I tried fetching data, setting state in Admin with componentDidMount
but it didn't re-render so I read to use componentWillReceiveProps
but that's being deprecated and replaced with getDerivedStateFromProps
. Could not figure that out.
login.jsx
import React, { Component, Fragment } from 'react';
import * as userService from '../../services/user';
import { Redirect } from 'react-router-dom';
import IndeterminateProgress from '../utilities/indeterminateprogress';
import Nav from '../home/nav';
class Login extends Component {
constructor(props) {
super(props);
this.state = {
redirectToReferrer: false,
email: '',
password: '',
feedbackMessage: '',
checkingLogin: true,
me: ''
};
}
componentDidMount() {
userService.checkLogin()
.then((loggedIn) => {
if (loggedIn) {
this.setState({ redirectToReferrer: true, checkingLogin: false });
} else {
this.setState({ checkingLogin: false });
}
});
}
login(e) {
e.preventDefault();
userService.login(this.state.email, this.state.password)
.then((meData) => {
this.setState({ redirectToReferrer: true, me: meData })
})
.catch((err) => {
if (err.message) {
this.setState({ feedbackMessage: err.message });
}
});
}
handleEmailChange(value) {
this.setState({ email: value });
}
handlePasswordChange(value) {
this.setState({ password: value });
}
render() {
const { from } = this.props.location.state || { from: { pathname: '/admin', state: { ...this.state } } };
const { redirectToReferrer, checkingLogin } = this.state;
if (checkingLogin) {
return <IndeterminateProgress message="Checking Login Status..." />;
}
if (redirectToReferrer) {
return (
<Redirect to={from} />
);
}
return (
<Fragment>
<Nav />
<h2 className="heading center">Login to continue</h2>
<form className="center" onSubmit={(e) => this.login(e)}>
<div className="form-group">
<input
placeholder="Email"
id="email"
className="col-3"
type="email"
onChange={(e) => this.handleEmailChange(e.target.value)}
required
/>
</div>
<div className="form-group">
<input
placeholder="Password"
id="password"
className="col-3"
type="password"
onChange={(e) => this.handlePasswordChange(e.target.value)}
required
/>
</div>
{this.state.feedbackMessage ? (
<p>{this.state.feedbackMessage}</p>
) : null}
<input type="submit" value="Login" className="btn btn-info btn-sm" />
</form>
</Fragment>
);
}
}
export { Login };
admin.jsx
import React, { Component } from 'react';
import Nav from '../home/nav';
import AdminBlogContainer from './adminblogcontainer'
import { BrowserRouter as Router, Link } from 'react-router-dom';
const Admin = (props) => {
return (
<div className="flexcol center">
<Nav />
<h1 className="heading">Your Blog Posts</h1>
<AdminBlogContainer {...props.location.state.me} />
<Link to={{
pathname: '/write',
state: { ...props.location.state.me }
}}
className="btn btn-outline-secondary mt-4"
>Create a New Blog Post</Link>
</div>
)
}
export { Admin };
privateroute.jsx
import React from 'react';
import { Route, Redirect } from 'react-router-dom';
import { isLoggedIn } from '../../services/user';
const PrivateRoute = (props) => {
const Component = props.component;
const propsToPass = Object.assign({}, props);
delete propsToPass.component;
return (
<Route {...propsToPass} render={props => (
isLoggedIn() ? (
<Component {...props} />
) : (
<Redirect to={{
pathname: '/login',
state: { from: props.location }
}} />
)
)} />
);
};
export { PrivateRoute }
authbutton.jsx
import React from 'react';
import { Link } from 'react-router-dom';
import { isLoggedIn } from '../../services/user';
const AuthButton = (props) => {
if (isLoggedIn()) {
return (
<div>
<Link className="btn btn-info m-1" to="/logout">Logout</Link>
<Link className='btn btn-info m-1' to={{
pathname: '/admin',
// state: { ...this.state }
}}
>My Posts</Link>
</div>
);
} else {
return (
<div>
<Link className="btn btn-info m-1" to="/login">Login</Link>
<Link className="btn btn-info m-1" to="/register">Register</Link>
</div>
)
}
};
export { AuthButton };
javascript reactjs react-router basic-authentication react-props
add a comment |
I'm creating a React Router app and I'm learning authentication. Here are some parts:
Login component (login.jsx)
- authenticates user's credential on the back end
- sets the authentication token in local storage
- return's the user's data
- sets state with the data
- passes state to Admin component
Admin component (admin.jsx)
- protected by a private route (see privateroute.jsx)
- basically a container component
- passes user's data to and renders other components that display/edit the data
Authentication Button on the nav bar (authbutton.jsx)
- checks if user is logged in and renders "login" or "logout" button
- if logged in, also renders "my posts" button that routes to Admin
All works well from Login to Admin. My problem is that when I click away from the Admin page (like the home page) and then click on "my posts" button, it reroutes to Admin and knows I'm logged in, but the user's data is no longer available. Before, coming from the login component, the user's data was in this.props.location.state.me
.
I'm stuck because I'm trying to route to Admin from two different components and I've never done that before. Furthermore, I feel like there's a solution in the authentication setup that I'm missing.
Other ideas:
Should I conditionally set state in Admin when the user's data is passed?
Should I store the data in local storage in the browser like I'm doing with the authentication token?
I tried fetching data, setting state in Admin with componentDidMount
but it didn't re-render so I read to use componentWillReceiveProps
but that's being deprecated and replaced with getDerivedStateFromProps
. Could not figure that out.
login.jsx
import React, { Component, Fragment } from 'react';
import * as userService from '../../services/user';
import { Redirect } from 'react-router-dom';
import IndeterminateProgress from '../utilities/indeterminateprogress';
import Nav from '../home/nav';
class Login extends Component {
constructor(props) {
super(props);
this.state = {
redirectToReferrer: false,
email: '',
password: '',
feedbackMessage: '',
checkingLogin: true,
me: ''
};
}
componentDidMount() {
userService.checkLogin()
.then((loggedIn) => {
if (loggedIn) {
this.setState({ redirectToReferrer: true, checkingLogin: false });
} else {
this.setState({ checkingLogin: false });
}
});
}
login(e) {
e.preventDefault();
userService.login(this.state.email, this.state.password)
.then((meData) => {
this.setState({ redirectToReferrer: true, me: meData })
})
.catch((err) => {
if (err.message) {
this.setState({ feedbackMessage: err.message });
}
});
}
handleEmailChange(value) {
this.setState({ email: value });
}
handlePasswordChange(value) {
this.setState({ password: value });
}
render() {
const { from } = this.props.location.state || { from: { pathname: '/admin', state: { ...this.state } } };
const { redirectToReferrer, checkingLogin } = this.state;
if (checkingLogin) {
return <IndeterminateProgress message="Checking Login Status..." />;
}
if (redirectToReferrer) {
return (
<Redirect to={from} />
);
}
return (
<Fragment>
<Nav />
<h2 className="heading center">Login to continue</h2>
<form className="center" onSubmit={(e) => this.login(e)}>
<div className="form-group">
<input
placeholder="Email"
id="email"
className="col-3"
type="email"
onChange={(e) => this.handleEmailChange(e.target.value)}
required
/>
</div>
<div className="form-group">
<input
placeholder="Password"
id="password"
className="col-3"
type="password"
onChange={(e) => this.handlePasswordChange(e.target.value)}
required
/>
</div>
{this.state.feedbackMessage ? (
<p>{this.state.feedbackMessage}</p>
) : null}
<input type="submit" value="Login" className="btn btn-info btn-sm" />
</form>
</Fragment>
);
}
}
export { Login };
admin.jsx
import React, { Component } from 'react';
import Nav from '../home/nav';
import AdminBlogContainer from './adminblogcontainer'
import { BrowserRouter as Router, Link } from 'react-router-dom';
const Admin = (props) => {
return (
<div className="flexcol center">
<Nav />
<h1 className="heading">Your Blog Posts</h1>
<AdminBlogContainer {...props.location.state.me} />
<Link to={{
pathname: '/write',
state: { ...props.location.state.me }
}}
className="btn btn-outline-secondary mt-4"
>Create a New Blog Post</Link>
</div>
)
}
export { Admin };
privateroute.jsx
import React from 'react';
import { Route, Redirect } from 'react-router-dom';
import { isLoggedIn } from '../../services/user';
const PrivateRoute = (props) => {
const Component = props.component;
const propsToPass = Object.assign({}, props);
delete propsToPass.component;
return (
<Route {...propsToPass} render={props => (
isLoggedIn() ? (
<Component {...props} />
) : (
<Redirect to={{
pathname: '/login',
state: { from: props.location }
}} />
)
)} />
);
};
export { PrivateRoute }
authbutton.jsx
import React from 'react';
import { Link } from 'react-router-dom';
import { isLoggedIn } from '../../services/user';
const AuthButton = (props) => {
if (isLoggedIn()) {
return (
<div>
<Link className="btn btn-info m-1" to="/logout">Logout</Link>
<Link className='btn btn-info m-1' to={{
pathname: '/admin',
// state: { ...this.state }
}}
>My Posts</Link>
</div>
);
} else {
return (
<div>
<Link className="btn btn-info m-1" to="/login">Login</Link>
<Link className="btn btn-info m-1" to="/register">Register</Link>
</div>
)
}
};
export { AuthButton };
javascript reactjs react-router basic-authentication react-props
add a comment |
I'm creating a React Router app and I'm learning authentication. Here are some parts:
Login component (login.jsx)
- authenticates user's credential on the back end
- sets the authentication token in local storage
- return's the user's data
- sets state with the data
- passes state to Admin component
Admin component (admin.jsx)
- protected by a private route (see privateroute.jsx)
- basically a container component
- passes user's data to and renders other components that display/edit the data
Authentication Button on the nav bar (authbutton.jsx)
- checks if user is logged in and renders "login" or "logout" button
- if logged in, also renders "my posts" button that routes to Admin
All works well from Login to Admin. My problem is that when I click away from the Admin page (like the home page) and then click on "my posts" button, it reroutes to Admin and knows I'm logged in, but the user's data is no longer available. Before, coming from the login component, the user's data was in this.props.location.state.me
.
I'm stuck because I'm trying to route to Admin from two different components and I've never done that before. Furthermore, I feel like there's a solution in the authentication setup that I'm missing.
Other ideas:
Should I conditionally set state in Admin when the user's data is passed?
Should I store the data in local storage in the browser like I'm doing with the authentication token?
I tried fetching data, setting state in Admin with componentDidMount
but it didn't re-render so I read to use componentWillReceiveProps
but that's being deprecated and replaced with getDerivedStateFromProps
. Could not figure that out.
login.jsx
import React, { Component, Fragment } from 'react';
import * as userService from '../../services/user';
import { Redirect } from 'react-router-dom';
import IndeterminateProgress from '../utilities/indeterminateprogress';
import Nav from '../home/nav';
class Login extends Component {
constructor(props) {
super(props);
this.state = {
redirectToReferrer: false,
email: '',
password: '',
feedbackMessage: '',
checkingLogin: true,
me: ''
};
}
componentDidMount() {
userService.checkLogin()
.then((loggedIn) => {
if (loggedIn) {
this.setState({ redirectToReferrer: true, checkingLogin: false });
} else {
this.setState({ checkingLogin: false });
}
});
}
login(e) {
e.preventDefault();
userService.login(this.state.email, this.state.password)
.then((meData) => {
this.setState({ redirectToReferrer: true, me: meData })
})
.catch((err) => {
if (err.message) {
this.setState({ feedbackMessage: err.message });
}
});
}
handleEmailChange(value) {
this.setState({ email: value });
}
handlePasswordChange(value) {
this.setState({ password: value });
}
render() {
const { from } = this.props.location.state || { from: { pathname: '/admin', state: { ...this.state } } };
const { redirectToReferrer, checkingLogin } = this.state;
if (checkingLogin) {
return <IndeterminateProgress message="Checking Login Status..." />;
}
if (redirectToReferrer) {
return (
<Redirect to={from} />
);
}
return (
<Fragment>
<Nav />
<h2 className="heading center">Login to continue</h2>
<form className="center" onSubmit={(e) => this.login(e)}>
<div className="form-group">
<input
placeholder="Email"
id="email"
className="col-3"
type="email"
onChange={(e) => this.handleEmailChange(e.target.value)}
required
/>
</div>
<div className="form-group">
<input
placeholder="Password"
id="password"
className="col-3"
type="password"
onChange={(e) => this.handlePasswordChange(e.target.value)}
required
/>
</div>
{this.state.feedbackMessage ? (
<p>{this.state.feedbackMessage}</p>
) : null}
<input type="submit" value="Login" className="btn btn-info btn-sm" />
</form>
</Fragment>
);
}
}
export { Login };
admin.jsx
import React, { Component } from 'react';
import Nav from '../home/nav';
import AdminBlogContainer from './adminblogcontainer'
import { BrowserRouter as Router, Link } from 'react-router-dom';
const Admin = (props) => {
return (
<div className="flexcol center">
<Nav />
<h1 className="heading">Your Blog Posts</h1>
<AdminBlogContainer {...props.location.state.me} />
<Link to={{
pathname: '/write',
state: { ...props.location.state.me }
}}
className="btn btn-outline-secondary mt-4"
>Create a New Blog Post</Link>
</div>
)
}
export { Admin };
privateroute.jsx
import React from 'react';
import { Route, Redirect } from 'react-router-dom';
import { isLoggedIn } from '../../services/user';
const PrivateRoute = (props) => {
const Component = props.component;
const propsToPass = Object.assign({}, props);
delete propsToPass.component;
return (
<Route {...propsToPass} render={props => (
isLoggedIn() ? (
<Component {...props} />
) : (
<Redirect to={{
pathname: '/login',
state: { from: props.location }
}} />
)
)} />
);
};
export { PrivateRoute }
authbutton.jsx
import React from 'react';
import { Link } from 'react-router-dom';
import { isLoggedIn } from '../../services/user';
const AuthButton = (props) => {
if (isLoggedIn()) {
return (
<div>
<Link className="btn btn-info m-1" to="/logout">Logout</Link>
<Link className='btn btn-info m-1' to={{
pathname: '/admin',
// state: { ...this.state }
}}
>My Posts</Link>
</div>
);
} else {
return (
<div>
<Link className="btn btn-info m-1" to="/login">Login</Link>
<Link className="btn btn-info m-1" to="/register">Register</Link>
</div>
)
}
};
export { AuthButton };
javascript reactjs react-router basic-authentication react-props
I'm creating a React Router app and I'm learning authentication. Here are some parts:
Login component (login.jsx)
- authenticates user's credential on the back end
- sets the authentication token in local storage
- return's the user's data
- sets state with the data
- passes state to Admin component
Admin component (admin.jsx)
- protected by a private route (see privateroute.jsx)
- basically a container component
- passes user's data to and renders other components that display/edit the data
Authentication Button on the nav bar (authbutton.jsx)
- checks if user is logged in and renders "login" or "logout" button
- if logged in, also renders "my posts" button that routes to Admin
All works well from Login to Admin. My problem is that when I click away from the Admin page (like the home page) and then click on "my posts" button, it reroutes to Admin and knows I'm logged in, but the user's data is no longer available. Before, coming from the login component, the user's data was in this.props.location.state.me
.
I'm stuck because I'm trying to route to Admin from two different components and I've never done that before. Furthermore, I feel like there's a solution in the authentication setup that I'm missing.
Other ideas:
Should I conditionally set state in Admin when the user's data is passed?
Should I store the data in local storage in the browser like I'm doing with the authentication token?
I tried fetching data, setting state in Admin with componentDidMount
but it didn't re-render so I read to use componentWillReceiveProps
but that's being deprecated and replaced with getDerivedStateFromProps
. Could not figure that out.
login.jsx
import React, { Component, Fragment } from 'react';
import * as userService from '../../services/user';
import { Redirect } from 'react-router-dom';
import IndeterminateProgress from '../utilities/indeterminateprogress';
import Nav from '../home/nav';
class Login extends Component {
constructor(props) {
super(props);
this.state = {
redirectToReferrer: false,
email: '',
password: '',
feedbackMessage: '',
checkingLogin: true,
me: ''
};
}
componentDidMount() {
userService.checkLogin()
.then((loggedIn) => {
if (loggedIn) {
this.setState({ redirectToReferrer: true, checkingLogin: false });
} else {
this.setState({ checkingLogin: false });
}
});
}
login(e) {
e.preventDefault();
userService.login(this.state.email, this.state.password)
.then((meData) => {
this.setState({ redirectToReferrer: true, me: meData })
})
.catch((err) => {
if (err.message) {
this.setState({ feedbackMessage: err.message });
}
});
}
handleEmailChange(value) {
this.setState({ email: value });
}
handlePasswordChange(value) {
this.setState({ password: value });
}
render() {
const { from } = this.props.location.state || { from: { pathname: '/admin', state: { ...this.state } } };
const { redirectToReferrer, checkingLogin } = this.state;
if (checkingLogin) {
return <IndeterminateProgress message="Checking Login Status..." />;
}
if (redirectToReferrer) {
return (
<Redirect to={from} />
);
}
return (
<Fragment>
<Nav />
<h2 className="heading center">Login to continue</h2>
<form className="center" onSubmit={(e) => this.login(e)}>
<div className="form-group">
<input
placeholder="Email"
id="email"
className="col-3"
type="email"
onChange={(e) => this.handleEmailChange(e.target.value)}
required
/>
</div>
<div className="form-group">
<input
placeholder="Password"
id="password"
className="col-3"
type="password"
onChange={(e) => this.handlePasswordChange(e.target.value)}
required
/>
</div>
{this.state.feedbackMessage ? (
<p>{this.state.feedbackMessage}</p>
) : null}
<input type="submit" value="Login" className="btn btn-info btn-sm" />
</form>
</Fragment>
);
}
}
export { Login };
admin.jsx
import React, { Component } from 'react';
import Nav from '../home/nav';
import AdminBlogContainer from './adminblogcontainer'
import { BrowserRouter as Router, Link } from 'react-router-dom';
const Admin = (props) => {
return (
<div className="flexcol center">
<Nav />
<h1 className="heading">Your Blog Posts</h1>
<AdminBlogContainer {...props.location.state.me} />
<Link to={{
pathname: '/write',
state: { ...props.location.state.me }
}}
className="btn btn-outline-secondary mt-4"
>Create a New Blog Post</Link>
</div>
)
}
export { Admin };
privateroute.jsx
import React from 'react';
import { Route, Redirect } from 'react-router-dom';
import { isLoggedIn } from '../../services/user';
const PrivateRoute = (props) => {
const Component = props.component;
const propsToPass = Object.assign({}, props);
delete propsToPass.component;
return (
<Route {...propsToPass} render={props => (
isLoggedIn() ? (
<Component {...props} />
) : (
<Redirect to={{
pathname: '/login',
state: { from: props.location }
}} />
)
)} />
);
};
export { PrivateRoute }
authbutton.jsx
import React from 'react';
import { Link } from 'react-router-dom';
import { isLoggedIn } from '../../services/user';
const AuthButton = (props) => {
if (isLoggedIn()) {
return (
<div>
<Link className="btn btn-info m-1" to="/logout">Logout</Link>
<Link className='btn btn-info m-1' to={{
pathname: '/admin',
// state: { ...this.state }
}}
>My Posts</Link>
</div>
);
} else {
return (
<div>
<Link className="btn btn-info m-1" to="/login">Login</Link>
<Link className="btn btn-info m-1" to="/register">Register</Link>
</div>
)
}
};
export { AuthButton };
javascript reactjs react-router basic-authentication react-props
javascript reactjs react-router basic-authentication react-props
asked Nov 25 '18 at 1:15
ChristyChristy
11910
11910
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
This is one of the reasons as to the creation of stores. Think of it as a global object that can be accessed anywhere within your application.
I personally have used mobx/mobx-react (easy and does things magically) and there is also redux
Using mobx you can do something like so:
Global store
// /stores/authentication.js
class AuthenticationStore {
user = {};
//authentication logic here
}
const authenticationStore = new AuthenticationStore();
export default authenticationStore;
Root App Component
// /app.js
import authenticationStore from './stores/authentication';
import { Provider } from 'mobx-react';
export default class App extends Component {
render(){
return (
<Provider authenticationStore={authenticationStore}>
<BrowserRouter>
<SomeComponent/>
</BrowserRouter>
<Provider>);
}
}
Some component;
// /components/some.component.js
@inject('authenticationStore')
class SomeComponent extends Component {
render(){
const {authenticationStore} = this.props;
const {user} = authenticationStore;
render(
<div>${user.name}</div>
)
}
}
1
ok, I can try this! would've been nice if the online school that gave me this assignment mentioned stores -_-
– Christy
Nov 25 '18 at 1:37
@Christy, you are not, of course, required to use them. You can pass objects via routes... but it gets tedious. If you have any more questions or more specific details let me know. ;)
– kemicofa
Nov 25 '18 at 1:38
@Christy mobx.js.org/best/store.html
– kemicofa
Nov 25 '18 at 1:55
add a comment |
There seem to be two main solutions to my problem. 1 is to use a store as answered on this page. The other is to store the data in local storage, which looks like:
in login.jsx set local storage instead of setting state
login(e) {
e.preventDefault();
userService.login(this.state.email, this.state.password)
.then((meData) => {
localStorage.setItem("me", JSON.stringify(meData))
this.setState({ redirectToReferrer: true})
})
.catch((err) => {
if (err.message) {
this.setState({ feedbackMessage: err.message });
}
});
}
retrieve data in adminblogcontainer.jsx
componentDidMount() {
let meData = JSON.parse((localStorage.getItem("me")))
authorsService.one(meData.id) ...
The downside when only using localStorage is that, you'll constantly have to retrieve the data when changing pages and update it when something happens. The combination of a store and using localStorage is really nice. On page load you retrieve user data (if exists otherwise create and save), and when the page is about to close (you update the user data in localstorage)
– kemicofa
Nov 28 '18 at 18:00
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53463862%2freact-router-how-to-keep-logged-in-data-props-when-re-routing%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
This is one of the reasons as to the creation of stores. Think of it as a global object that can be accessed anywhere within your application.
I personally have used mobx/mobx-react (easy and does things magically) and there is also redux
Using mobx you can do something like so:
Global store
// /stores/authentication.js
class AuthenticationStore {
user = {};
//authentication logic here
}
const authenticationStore = new AuthenticationStore();
export default authenticationStore;
Root App Component
// /app.js
import authenticationStore from './stores/authentication';
import { Provider } from 'mobx-react';
export default class App extends Component {
render(){
return (
<Provider authenticationStore={authenticationStore}>
<BrowserRouter>
<SomeComponent/>
</BrowserRouter>
<Provider>);
}
}
Some component;
// /components/some.component.js
@inject('authenticationStore')
class SomeComponent extends Component {
render(){
const {authenticationStore} = this.props;
const {user} = authenticationStore;
render(
<div>${user.name}</div>
)
}
}
1
ok, I can try this! would've been nice if the online school that gave me this assignment mentioned stores -_-
– Christy
Nov 25 '18 at 1:37
@Christy, you are not, of course, required to use them. You can pass objects via routes... but it gets tedious. If you have any more questions or more specific details let me know. ;)
– kemicofa
Nov 25 '18 at 1:38
@Christy mobx.js.org/best/store.html
– kemicofa
Nov 25 '18 at 1:55
add a comment |
This is one of the reasons as to the creation of stores. Think of it as a global object that can be accessed anywhere within your application.
I personally have used mobx/mobx-react (easy and does things magically) and there is also redux
Using mobx you can do something like so:
Global store
// /stores/authentication.js
class AuthenticationStore {
user = {};
//authentication logic here
}
const authenticationStore = new AuthenticationStore();
export default authenticationStore;
Root App Component
// /app.js
import authenticationStore from './stores/authentication';
import { Provider } from 'mobx-react';
export default class App extends Component {
render(){
return (
<Provider authenticationStore={authenticationStore}>
<BrowserRouter>
<SomeComponent/>
</BrowserRouter>
<Provider>);
}
}
Some component;
// /components/some.component.js
@inject('authenticationStore')
class SomeComponent extends Component {
render(){
const {authenticationStore} = this.props;
const {user} = authenticationStore;
render(
<div>${user.name}</div>
)
}
}
1
ok, I can try this! would've been nice if the online school that gave me this assignment mentioned stores -_-
– Christy
Nov 25 '18 at 1:37
@Christy, you are not, of course, required to use them. You can pass objects via routes... but it gets tedious. If you have any more questions or more specific details let me know. ;)
– kemicofa
Nov 25 '18 at 1:38
@Christy mobx.js.org/best/store.html
– kemicofa
Nov 25 '18 at 1:55
add a comment |
This is one of the reasons as to the creation of stores. Think of it as a global object that can be accessed anywhere within your application.
I personally have used mobx/mobx-react (easy and does things magically) and there is also redux
Using mobx you can do something like so:
Global store
// /stores/authentication.js
class AuthenticationStore {
user = {};
//authentication logic here
}
const authenticationStore = new AuthenticationStore();
export default authenticationStore;
Root App Component
// /app.js
import authenticationStore from './stores/authentication';
import { Provider } from 'mobx-react';
export default class App extends Component {
render(){
return (
<Provider authenticationStore={authenticationStore}>
<BrowserRouter>
<SomeComponent/>
</BrowserRouter>
<Provider>);
}
}
Some component;
// /components/some.component.js
@inject('authenticationStore')
class SomeComponent extends Component {
render(){
const {authenticationStore} = this.props;
const {user} = authenticationStore;
render(
<div>${user.name}</div>
)
}
}
This is one of the reasons as to the creation of stores. Think of it as a global object that can be accessed anywhere within your application.
I personally have used mobx/mobx-react (easy and does things magically) and there is also redux
Using mobx you can do something like so:
Global store
// /stores/authentication.js
class AuthenticationStore {
user = {};
//authentication logic here
}
const authenticationStore = new AuthenticationStore();
export default authenticationStore;
Root App Component
// /app.js
import authenticationStore from './stores/authentication';
import { Provider } from 'mobx-react';
export default class App extends Component {
render(){
return (
<Provider authenticationStore={authenticationStore}>
<BrowserRouter>
<SomeComponent/>
</BrowserRouter>
<Provider>);
}
}
Some component;
// /components/some.component.js
@inject('authenticationStore')
class SomeComponent extends Component {
render(){
const {authenticationStore} = this.props;
const {user} = authenticationStore;
render(
<div>${user.name}</div>
)
}
}
edited Nov 25 '18 at 1:32
answered Nov 25 '18 at 1:23
kemicofakemicofa
10.6k43983
10.6k43983
1
ok, I can try this! would've been nice if the online school that gave me this assignment mentioned stores -_-
– Christy
Nov 25 '18 at 1:37
@Christy, you are not, of course, required to use them. You can pass objects via routes... but it gets tedious. If you have any more questions or more specific details let me know. ;)
– kemicofa
Nov 25 '18 at 1:38
@Christy mobx.js.org/best/store.html
– kemicofa
Nov 25 '18 at 1:55
add a comment |
1
ok, I can try this! would've been nice if the online school that gave me this assignment mentioned stores -_-
– Christy
Nov 25 '18 at 1:37
@Christy, you are not, of course, required to use them. You can pass objects via routes... but it gets tedious. If you have any more questions or more specific details let me know. ;)
– kemicofa
Nov 25 '18 at 1:38
@Christy mobx.js.org/best/store.html
– kemicofa
Nov 25 '18 at 1:55
1
1
ok, I can try this! would've been nice if the online school that gave me this assignment mentioned stores -_-
– Christy
Nov 25 '18 at 1:37
ok, I can try this! would've been nice if the online school that gave me this assignment mentioned stores -_-
– Christy
Nov 25 '18 at 1:37
@Christy, you are not, of course, required to use them. You can pass objects via routes... but it gets tedious. If you have any more questions or more specific details let me know. ;)
– kemicofa
Nov 25 '18 at 1:38
@Christy, you are not, of course, required to use them. You can pass objects via routes... but it gets tedious. If you have any more questions or more specific details let me know. ;)
– kemicofa
Nov 25 '18 at 1:38
@Christy mobx.js.org/best/store.html
– kemicofa
Nov 25 '18 at 1:55
@Christy mobx.js.org/best/store.html
– kemicofa
Nov 25 '18 at 1:55
add a comment |
There seem to be two main solutions to my problem. 1 is to use a store as answered on this page. The other is to store the data in local storage, which looks like:
in login.jsx set local storage instead of setting state
login(e) {
e.preventDefault();
userService.login(this.state.email, this.state.password)
.then((meData) => {
localStorage.setItem("me", JSON.stringify(meData))
this.setState({ redirectToReferrer: true})
})
.catch((err) => {
if (err.message) {
this.setState({ feedbackMessage: err.message });
}
});
}
retrieve data in adminblogcontainer.jsx
componentDidMount() {
let meData = JSON.parse((localStorage.getItem("me")))
authorsService.one(meData.id) ...
The downside when only using localStorage is that, you'll constantly have to retrieve the data when changing pages and update it when something happens. The combination of a store and using localStorage is really nice. On page load you retrieve user data (if exists otherwise create and save), and when the page is about to close (you update the user data in localstorage)
– kemicofa
Nov 28 '18 at 18:00
add a comment |
There seem to be two main solutions to my problem. 1 is to use a store as answered on this page. The other is to store the data in local storage, which looks like:
in login.jsx set local storage instead of setting state
login(e) {
e.preventDefault();
userService.login(this.state.email, this.state.password)
.then((meData) => {
localStorage.setItem("me", JSON.stringify(meData))
this.setState({ redirectToReferrer: true})
})
.catch((err) => {
if (err.message) {
this.setState({ feedbackMessage: err.message });
}
});
}
retrieve data in adminblogcontainer.jsx
componentDidMount() {
let meData = JSON.parse((localStorage.getItem("me")))
authorsService.one(meData.id) ...
The downside when only using localStorage is that, you'll constantly have to retrieve the data when changing pages and update it when something happens. The combination of a store and using localStorage is really nice. On page load you retrieve user data (if exists otherwise create and save), and when the page is about to close (you update the user data in localstorage)
– kemicofa
Nov 28 '18 at 18:00
add a comment |
There seem to be two main solutions to my problem. 1 is to use a store as answered on this page. The other is to store the data in local storage, which looks like:
in login.jsx set local storage instead of setting state
login(e) {
e.preventDefault();
userService.login(this.state.email, this.state.password)
.then((meData) => {
localStorage.setItem("me", JSON.stringify(meData))
this.setState({ redirectToReferrer: true})
})
.catch((err) => {
if (err.message) {
this.setState({ feedbackMessage: err.message });
}
});
}
retrieve data in adminblogcontainer.jsx
componentDidMount() {
let meData = JSON.parse((localStorage.getItem("me")))
authorsService.one(meData.id) ...
There seem to be two main solutions to my problem. 1 is to use a store as answered on this page. The other is to store the data in local storage, which looks like:
in login.jsx set local storage instead of setting state
login(e) {
e.preventDefault();
userService.login(this.state.email, this.state.password)
.then((meData) => {
localStorage.setItem("me", JSON.stringify(meData))
this.setState({ redirectToReferrer: true})
})
.catch((err) => {
if (err.message) {
this.setState({ feedbackMessage: err.message });
}
});
}
retrieve data in adminblogcontainer.jsx
componentDidMount() {
let meData = JSON.parse((localStorage.getItem("me")))
authorsService.one(meData.id) ...
answered Nov 28 '18 at 17:24
ChristyChristy
11910
11910
The downside when only using localStorage is that, you'll constantly have to retrieve the data when changing pages and update it when something happens. The combination of a store and using localStorage is really nice. On page load you retrieve user data (if exists otherwise create and save), and when the page is about to close (you update the user data in localstorage)
– kemicofa
Nov 28 '18 at 18:00
add a comment |
The downside when only using localStorage is that, you'll constantly have to retrieve the data when changing pages and update it when something happens. The combination of a store and using localStorage is really nice. On page load you retrieve user data (if exists otherwise create and save), and when the page is about to close (you update the user data in localstorage)
– kemicofa
Nov 28 '18 at 18:00
The downside when only using localStorage is that, you'll constantly have to retrieve the data when changing pages and update it when something happens. The combination of a store and using localStorage is really nice. On page load you retrieve user data (if exists otherwise create and save), and when the page is about to close (you update the user data in localstorage)
– kemicofa
Nov 28 '18 at 18:00
The downside when only using localStorage is that, you'll constantly have to retrieve the data when changing pages and update it when something happens. The combination of a store and using localStorage is really nice. On page load you retrieve user data (if exists otherwise create and save), and when the page is about to close (you update the user data in localstorage)
– kemicofa
Nov 28 '18 at 18:00
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53463862%2freact-router-how-to-keep-logged-in-data-props-when-re-routing%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown