I'm trying to pass the state variable 'atoken' which holds an access token, to the child component 'Home' via localStorage, but when I try, localStorage.getItem(this.props.atoken) in the 'Home' component, an undefined value will show in the console. How can I properly pass this state variable (atoken) from the 'App' component to the 'Home' component?
import React, { Component } from 'react';
import Playlist from './components/playlist';
import Home from './components/Home';
import {
BrowserRouter as Router,
Route,
} from 'react-router-dom';
var Spotify = require('spotify-web-api-js');
var spotifyApi = new Spotify();
class App extends Component {
constructor(props){
super(props);
const params = this.getHashParams(); //tokens saved here
const token = params.access_token;
if (token) {
spotifyApi.setAccessToken(token);
}
this.state = {
loggedIn: token ? true : false,
atoken: token, //access token
};
window.localStorage.setItem(this.state.atoken, spotifyApi.getAccessToken());
console.log(window.localStorage.getItem(this.state.atoken));
}
getHashParams() { //uses authenticated users refresh and access token
var hashParams = {};
var e, r = /([^&;=]+)=?([^&;]*)/g,
q = window.location.hash.substring(1);
e = r.exec(q)
while (e) {
hashParams[e[1]] = decodeURIComponent(e[2]);
e = r.exec(q);
}
return hashParams;
}
render() {
return (
<Router>
<div className='App'>
<Route exact path = '/' component= {Home}/>
<Route path= '/playlist' component = {Playlist}/>
</div>
</Router>
);
}
}
export default App;
In the class 'Home', the state variable 'atoken' is not retrieving the access token from the parent component 'App'.
import React, { Component } from 'react';
import './App.css';
var Spotify = require('spotify-web-api-js');
var spotifyApi = new Spotify();
class Home extends Component {
constructor(props){
super(props);
this.state = {
year: ' ',
atoken: window.localStorage.getItem(this.props.atoken), //access token
};
console.log(this.state.atoken);
this.handleSubmit = this.handleSubmit.bind(this);
this.updateInput = this.updateInput.bind(this);
}
handleSubmit(event){
alert("Year Submitted");
this.props.history.push({
pathname: '/playlist',
state: {year: this.state.year, atoken: this.state.atoken},
});
event.preventDefault();
}
updateInput(event){
this.setState({year : event.target.value})
}
render() {
return (
<div id="body" className="Home">
<div>
<form onSubmit={this.handleSubmit}>
<input id = "yearInput" autoComplete="off" type="text" placeholder = "Enter Year" onChange={this.updateInput} />
</form>
</div>
<div id ="logout">
<a href='http://localhost:8888' >
<button id="logout_btn"> Logout </button>
</a>
</div>
</div>
);
}
}
export default Home;
So the issue is how you are trying to use local storage. When setting local storage, it takes two variables. The first is the unique name of the item you want to store and the second is the value. So when you are calling setItem it should be localStorage.setItem('name',value)
. Right now you are trying to pass two seperate tokens to storage. you would be doing.
window.localStorage.setItem('mySpotifyToken', spotifyApi.getAccessToken())
window.localStorage.setItem('otherTokenName', this.state.atoken)
Then you can access them in your home class by calling:
window.localStorage.getItem('mySpotifyToken')
window.localStorage.getItem('otherTokenName')
In your class Home, you are calling this.props.atoken, but you are not passing in anything via props so it will be undefined.
https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage