Handling signin flow in React - reactjs

I'm trying to implement Last.fm signin in React. After the user logins to Last.fm, they are redirected to
http://localhost:3000/loginlanding/?token=${token id goes here}
How do I capture the url using React Router?
So far, I have tried all these:
path="/loginlanding/?token:id"
path="/loginlanding/:id"
path="/loginlanding/?:id"
None of these seem to work.
Basically, I need to capture the access token and store it in global state.

specify route
<Route path="/loginlanding/:token_id" component={LoginLanding} />
pass token
<Link to=`/loginlanding/${token_id}` />
get token
this.props.match.params.token_id

**you can store your token in the localstorage and access it from there whenever needed.
Or if the token is available in the parent component you can access it as a prop like this.
**
{match:{params:{id}}} //<<<< This can be accessed in the react-router

Related

React - How to navigate using a custom component instead of react-router-dom

I have a rooms list that I iterate, rendering the different rooms like this:
<Room room={room} key={room.id}/>
I want each room to redirect to their corresponding path (/rooms/:id). The only way of redirecting elements is via react-router-dom but I feel there must be a better way of achieving redirection in this case.
React router works fine, only thing you need is pass id to link
<Route path="/RoomsList/:roomId" element={<RoomCard/>}/>
in RoomCard you use hook
const {roomId} = useParams();
and change the component depending on the id.

React Route overriding redux thunk reducer fetch call

I have a weird issue, I have a navlink that routes to /posts/:postId and in my app component a route that registers that to view a single post. When I dispatch , my thunk route is different to hit my backend, (im using the same route in separate components). Yet in this component when I dispatch it adds on a /posts at the beginning of the route I need to hit so it always errors out saying not found, because it does not exists. but when I change the navlink to exclude /posts and make it just /${postId} everything works just fine. Not sure why the Route is adding on a /posts prefix to my csrf fetch call. You guys ever run into something like this before?
<Route path='/posts/:postId' exact={true} >
<SinglePost />
</Route>
<NavLink className='delete-post-content' to={`posts/${postId}`}>Go to post</NavLink>
const response = await csrfFetch(`api/users/posts/${comment.postId}/comments/delete`,
when you link to posts/ its a relative address
but
when you link to /posts/ its a absolute path
so make sure to use a slash(/) before link

How to persist logged in user without going back?

I'm currently working on a web platform using React Js. I have stored backend token into my local storage but once the user signed in successfully then he should not go back with browser back arrow click. He should persist in the same page so how can I do it in react js? can I use useEffect hook there? Or I have to write any conditions for that? Only by clicking Logout button he should come back not with browser coming back arrow. Some people did it using componentDidMount but I'm in functional component so I used useEffect but It was not working. I tried multiple ways but unable to find solution. How can I achieve it in react js?
Thanks in advance.
You can use a user context, where upon login the user information is stored in localStorage and in the context api.
const storeUser = ({user, token}) => {
localStorage.setItem('user', JSON.stringify(user));
localStorage.setItem('token', token);
setUserState((prevUserState) => ({ ...prevUserState, user, token}));
};
then your data will be persisted throughout the website as long as you implement your user context correctly. To be clear, if you implement the context correctly, pressing back won't clear the localStorage or user state.
I'm afraid that if you try and implement it in a functional component by itself, the data will be wiped on re-render.
If you want to check whether or not a user has signed in then you can modify your site to allow access only to users that have signed in, by either coding it inline
{user.singedIn ? (<h1>Hello user</h1>) : (<h1>please sign in</h1>)
or in your routes
<Route path='/' element={!user ? <Navigate replace to='/login' /> : <Home />} />

Passing Access Token from an api to different pages

So I'm currently using the Spotify API with reactJS and get the access token of a user when the login is authenticated by Spotify, it redirects to the first page that I set it to, ('/') of Component={Home}. But from that Home page, I want to route to a different page with the path '/playlist' onClick of a button in which I push the url by,
this.props.history.push('/playlist/#access_tokens=' + spotifyApi.getAccessTokens())
This is the only way I got it to be with the access token passing in the URL.
Is this bad practice?
it's hard to understand your goals for me, but if you want to pass access_token only by url, you can use state to hide token from the user
this.props.history.push({
pathname: '/playlist',
state: {
accessTokens: spotifyApi.getAccessTokens()
}
})
and then get it by the next way
const location = useLocation();
const tokens = location.state && location.state.accessTokens;
But i can't understand why do not you pass your token to any management library like redux, mobx or some other browser storage (localStorage, sessionStorage)?

Reactjs router - this.props.history.push is not rendering URL queries from same path

I have a component that uses history.push to navigate URLs. The problem is that one of the URL paths relies on search parameters in the URL to render parts of the component. It works fine when the user initially navigates to the url, but when they update it while inside that path it doesn't work. Heres's an example:
App.js
<Router>
<Route path="/jobs" component={Jobs} />
</Router>
The url for jobs will contain a job ID, which is used to retrieve the data from the backend - ex: /jobs?id=6583ghawo90. With that id I make a get request inside componentDidMount() of the Jobs component to populate the page. Inside the Jobs component a user can navigate to a new job, which updates the url through this.props.history.push(`/jobs?id=${newjob.id}`). The problem is, when the user navigates to the updated URL, the component doesn't call componentDidMount() therefore doesn't request the new data. I can fix this by manually calling this.componentDidMount(), but this doesn't work if the user hits the back button in their browser.
Is there anything I can do to fix this issue?
You shouldn't be using componentDidMount but componentDidUpdate:
componentDidUpdate(prevProps) {
// compare previous jobId and current jobId
// refetch data if needed
}
I would suggest you use hooks if you are in the beginning of the development process.

Resources