Reputation: 10033
I'm new to React, sorry if this is too basic.
I have an app which has an api token which needs to be passed down as props
to many components, but which is not fetched at Parent component App.jsx.
My token is fetched at child component Spotify.jsx, and so I've tried to implement this like so:
this.state.spotifyToken = ''
at Parent component onConnectWithSpotify()
, also at Parentprops
this.state.spotifyToken
back at ParentMy components:
App.jsx (parent component):
class App extends Component {
constructor() {
super();
this.state = {
spotifyToken: ''
};
this.onConnectWithSpotify = this.onConnectWithSpotify.bind(this);
};
// --> callback
onConnectWithSpotify(token){
this.setState({ spotifyToken: token});
}
render() {
return (
<div>
<Route exact path='/' render={() => (
<SpotifyAuth
onConnectWithSpotify={this.onConnectWithSpotify}
spotifyToken={this.state.spotifyToken}// --> pass here
/>
)} />
</div>
)
}
Spotify.jsx (child component):
handleRedirect(event) {
const params = this.getHashParams();
const access_token = params.access_token;
console.log(access_token); // --> this prints valid token to console
const state = generateRandomString(16);
localStorage.setItem(Credentials.stateKey, state);
let url = 'https://accounts.spotify.com/authorize';
url += '?response_type=token';
url += '&client_id=' + encodeURIComponent(Credentials.client_id);
url += '&scope=' + encodeURIComponent(Credentials.scope);
url += '&redirect_uri=' + encodeURIComponent(Credentials.redirect_uri);
url += '&state=' + encodeURIComponent(state);
this.props.onConnectWithSpotify(access_token); // --> callback here
const {spotifyToken} = this.props
console.log('Spotify Token', spotifyToken); // --> this prints token undefined
window.location = url;
console.log(window.location )
};
Somehow I'm not managing to update this.state.spotifyToken
at Child. I'm getting 'undefined' at console.
What am I missing?
Upvotes: 0
Views: 240
Reputation: 243
You should consider using react context api. https://reactjs.org/docs/context.html If you set your api token in the context object of the parent. Any child component can view the context data. Since you need to update the data from a child, the context object should also contain a function to update data by the parent.
import React from 'react'
const AppContext = React.createContext()
export default AppContext
const Parent = () => {
const [ token, setToken ] = useState(null)
<AppContext.Provider value={token:token, setToken:setToken}>
......
</...>
}
import React, { useState, useContext, useEffect } from 'react'
const Child = () => {
const { token, setToken } = useContext(AppContext);
return (
....
)
}
Upvotes: 0
Reputation: 59
setState method takes a callback function as a parameter in case you need to do something right after the state gets updated. setState(updater, [callback])
If you want to print the token when it gets updated then you could do something like this
onConnectWithSpotify(token){
this.setState({
spotifyToken: token
}, () => {
console.log('Spotify Token', this.state.spotifyToken)
})
}
Also, the reason why it is printing undefined is because you are accessing the props wrong. you need to do
console.log('Spotify Token', this.props.spotifyToken);
Upvotes: 1