当通过setVariables发出请求时,是否有办法考虑异步请求之间的本地状态,即实现加载指示符?
向https://www.graphqlHub.com/graphql
发出请求的插图 _onChange = (ev) => {
this.setState({
loading:true
})
let gifType = ev.target.value;
this.props.relay.setVariables({
gifType
});
this.setState({
loading:false
})
}
这将不会跟踪加载状态,并且加载将立即传递给false,而异步更改到视图将有滞后。
如果我们将加载移动到setVariables有没有办法跟踪响应?在根容器中,可以通过
跟踪响应 renderLoading={function() {
return <div>Loading...</div>;
}}
是否有Relay.createContainer
使用setVariables导航数据集是不好的做法吗?
完整代码
class GiphItems extends React.Component {
constructor(){
super();
this.state = {
loading: false
}
}
render() {
const random = this.props.store.random
return <div>
<select onChange={this._onChange.bind(this)} value={this.props.relay.variables.gifType}>
<option value="sexy">Sexy</option>
<option value="cats">Cats</option>
<option value="goal">Goal</option>
<option value="lol">LOL</option>
</select>
{this.state.loading ? 'LOADING' : <a href={random.url}><img src={random.images.original.url} className="img-responsive"/></a>}
</div>;
}
_onChange = (ev) => {
this.setState({
loading:true
})
let gifType = ev.target.value;
this.props.relay.setVariables({
gifType
});
this.setState({
loading:false
})
}
}
GiphItems = Relay.createContainer(GiphItems, {
initialVariables: {
gifType: "sexy"
},
fragments: {
store: () => Relay.QL`
fragment on GiphyAPI {
random(tag: $gifType ) {
id
url
images {
original {
url
}
}
}
}
`,
},
});
答案 0 :(得分:0)
好问题。在处理特定组件的加载屏幕方面,您所拥有的是一个可行的选择。但是,对于每个单独组件的每个加载方案,这都可能成为一种负担。
如果要提供更通用的解决方案,您可以执行以下操作:您可以在React应用程序中设置全局事件系统,该系统将根据呼叫是否为每个组件广播全局状态正在制作对于您需要的每个组件,您可以从componentDidMount()
订阅此全局事件,并使用componentWillUnmount()
取消订阅。只要您的组件看到此全局状态发生更改,该组件就应调用setState()
,这将确定该组件是否应显示加载场景。
这是学习如何在组件之间进行通信以建立全局事件系统的好资源: https://facebook.github.io/react/tips/communicate-between-components.html
您也可以使用Facebook的Flux来实现这一点: https://facebook.github.io/flux/
希望这有帮助!
答案 1 :(得分:0)
setVariables方法还接受一个回调作为第二个参数,它响应数据实现所涉及的事件,并接收一个你可以检查的'readyState'对象:
this.props.relay.setVariables({
gifType,
}, (readyState)=> {
if (!readyState.done) {
this.setState({
loading: true
})
} else if(readyState.done) {
this.setState({
loading: false
})
}
})