反应-将子值传递为道具

时间:2019-10-22 02:45:37

标签: javascript reactjs

我是React的新手,如果这太基础了,就对不起。

我有一个带有api令牌的应用程序,该令牌需要作为props传递给许多组件,但在父组件App.jsx上不会获取。

我的令牌是在子组件Spotify.jsx处获取的,因此我试图这样实现:

  1. 在父组件上使用this.state.spotifyToken = ''设置我的令牌
  2. 也在父级创建一个回调函数onConnectWithSpotify()
  3. 将此回调函数作为props传递给子组件
  4. 调用函数并在父级上更新this.state.spotifyToken

我的组件:

App.jsx (父组件):

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 (子组件):

  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 )
};

以某种方式,我无法在Child上更新this.state.spotifyToken。我在控制台上得到“未定义”。

我想念什么?

2 个答案:

答案 0 :(得分:1)

setState方法将回调函数作为参数,以防您需要在状态更新后立即执行某些操作。 setState(updater,[callback])

如果您想在令牌更新时打印令牌,则可以执行以下操作

onConnectWithSpotify(token){
   this.setState({ 
      spotifyToken: token
   }, () => {
      console.log('Spotify Token', this.state.spotifyToken)
   })
}

另外,它打印不确定的原因是因为您错误地访问了道具。你需要做

console.log('Spotify Token', this.props.spotifyToken);

答案 1 :(得分:0)

您应该考虑使用react上下文api。 https://reactjs.org/docs/context.html 如果您在父级的上下文对象中设置api令牌。任何子组件都可以查看上下文数据。由于您需要从子级更新数据,因此上下文对象还应包含一个由父级更新数据的功能。

  1. 在名为AppContext.js的其他文件中定义上下文
import React from 'react'
const AppContext = React.createContext()
export default AppContext
  1. 您的主要父母将具有包含令牌的状态,并具有更新令牌的功能。父母会提供上下文
const Parent = () => {
    const [ token, setToken ] = useState(null)
    <AppContext.Provider value={token:token, setToken:setToken}>
       ......
    </...>
}
  1. 您的子组件将成为此上下文的使用者。在子组件中导入上下文。
  2. 使用react中的'useContext'API。您将从子组件中访问令牌和功能
import React, { useState, useContext, useEffect } from 'react'
const Child = () => {
   const { token, setToken } = useContext(AppContext);
   return (
     ....
   )
}