我在这里做最后一件事时遇到了麻烦。我需要获取从_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}/>
});
}
答案 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>
);
}
}