【问题标题】:React - pass child value as propsReact - 将子值作为道具传递
【发布时间】:2020-02-18 03:24:42
【问题描述】:

我是 React 新手,如果这太基础了,请见谅。

我有一个应用程序,它有一个 api 令牌,需要作为 props 传递给许多组件,但在父组件 App.jsx 中没有获取。

我的令牌是在子组件 Spotify.jsx 中获取的,所以我尝试这样实现:

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

我的组件:

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。我在控制台得到“未定义”。

我错过了什么?

【问题讨论】:

  • 您可能还需要将spotifyToken 作为道具传递给子组件。
  • console.log('Spotify Token', this.props.spotify_token); // --&gt; this prints token undefined。您的 Spotify component 不包含名为 spotify_token 的道具
  • 您通过调用onConnectWithSpotify 更改父级的状态,React 需要一些时间来重新渲染您的组件。因此,它不会立即在您的 handleRedirect 中更新,它仍然是旧的 spotifyToken 值,即 ''
  • 完全有道理。那么解决方案是什么?
  • 如果你使用类添加componentDidUpdate,如果你使用函数来观察变化,则添加'useEffect'。

标签: javascript reactjs


【解决方案1】:

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

如果你想在更新时打印令牌,那么你可以这样做

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

此外,它打印 undefined 的原因是因为您访问道具错误。你需要做的

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

【讨论】:

    【解决方案2】:

    您应该考虑使用反应上下文 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 (
         ....
       )
    }
    
    

    【讨论】:

      猜你喜欢
      • 2019-05-02
      • 2023-03-12
      • 2018-08-01
      • 1970-01-01
      • 2022-01-24
      • 2020-06-12
      • 1970-01-01
      • 2016-03-19
      相关资源
      最近更新 更多