将函数返回对象赋给变量并将其作为prop传递给组件

时间:2016-06-28 16:48:48

标签: javascript reactjs

我在这里做最后一件事时遇到了麻烦。我需要获取从_request方法返回的对象,并将其分配给render方法中的propVals变量,然后将该变量传递给SingleChannel组件上的channelValues prop,如您所见。我的问题是,当我返回SingleChannel组件时,propVals是未定义的。我知道if语句正在返回它们应该是什么,因此问题是在propVals收到对象之前正在呈现SingleChannel组件。我真的不知道还能做什么。我也试过直接从SingleChannel组件调用方法,如channelValues = {this._request(channel.name)}。

_request(name) {
HTTP.call('GET', `https://api.twitch.tv/kraken/streams/${name}`,
  {headers: {Accept: 'application/vnd.twitchtv.v3+json'} },
  function(error, response) {
    if(error) {
      console.log(error)
    } else {
      if(response.data.stream === null) {
        return {streaming: false, game: "Not playing anything"}

      } else {
        return {streaming: true, game: response.data.stream.game}


      }
    }

  });
}
renderChannels() {
  const channels = this.props.channels;
  console.log(channels)
  return channels.map((channel) => {
    const propVals = this._request(channel.name);
    //console.log(propVals);
    return <SingleChannel key={channel._id} channel={channel} channelValues={propVals}/>

  });


}

2 个答案:

答案 0 :(得分:0)

由于存在AJAX调用(异步逻辑),建议使用componentDidMount

componentDidMount:function(){
     var that=this;
     this._request(name,function(){
       that.setState({propVals:propVals})
     });

}

在AJAX回调中,请致电setState

_request(name,fnback) {

      //if success 
      fnback.call(null);
}

然后,在render中使用this.state.propVals

return <SingleChannel key={channel._id} channel={channel} channelValues={this.state.propVals}/>

答案 1 :(得分:0)

问题是,在if语句中,您要从回调函数返回值,而不是从_request()返回。

由于_request是异步函数,在回调中,您应该使用setState方法将派生数据添加到当前状态。

考虑这种方法:

class Parent extends Component {
    constructor(props) {
        super(props)

        this.state = {
            values: {}
        };

        this._request = this._request.bind(this);
    }

    componentWillMount() {
        // Iterating through channels, and calling `_request` for each channel.
        this.props.channels.forEach(this._request);
    }

    // We are accepting whole `channel` variable, instead of `name`.
    // As we need access to `channel._id` from this function.
    _request(channel) {
        HTTP.call('GET', `https://api.twitch.tv/kraken/streams/${channel.name}`, {
            headers: {
                Accept: 'application/vnd.twitchtv.v3+json'
            },
        }, (error, response) => {
            if (error) {
                console.log(error)
            } else {
                let result;

                if (response.data.stream === null) {
                    result = {
                        streaming: false,
                        game: "Not playing anything"
                    };
                } else {
                    result = {
                        streaming: true,
                        game: response.data.stream.game
                    }
                }

                // Adding result to state. It forces component to rerender with derived data.
                // Note, we need to use `Object.assign` to avoid state mutations.
                this.setState({
                    values: Object.assign({}, this.state.values, {
                        [channel._id]: result,
                    })
                });
            }
        });
    }

    render() {
        return (
            <div>
                {this.props.channels.map(channel => {
                    return (
                        <SingleChannel
                            key={channel._id}
                            channel={channel}
                            channelValues={this.state.values[channel._id]}
                        />
                    );
                })}
            </div>
        );
    }
}