8-Bit Borges
8-Bit Borges

Reputation: 10033

React - pass child value as props

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:

  1. set my token with this.state.spotifyToken = '' at Parent component
  2. create a callback function onConnectWithSpotify(), also at Parent
  3. pass this callback function to Child component as props
  4. call function and update this.state.spotifyToken back at Parent

My 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

Answers (2)

Inayath Ebrahim
Inayath Ebrahim

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.

  1. Define context in different file named AppContext.js
import React from 'react'
const AppContext = React.createContext()
export default AppContext
  1. You main parent will have state containing token and function to update the token. Parent will provide context
const Parent = () => {
    const [ token, setToken ] = useState(null)
    <AppContext.Provider value={token:token, setToken:setToken}>
       ......
    </...>
}
  1. You child component will be the consumer of this context. Import context in child component.
  2. Use 'useContext' api from react. You will get access to the token and function from your child component
import React, { useState, useContext, useEffect } from 'react'
const Child = () => {
   const { token, setToken } = useContext(AppContext);
   return (
     ....
   )
}

Upvotes: 0

negool
negool

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

Related Questions