2016-07-15 156 views
0

当通过setVariables发出请求时,是否有一种方法可以考虑异步请求之间的本地状态,即实现加载指示器?通过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 
    }) 
    } 

这不会跟踪装载状态和载荷将立即传递到假,而异步变化到视图将具有滞后。

如果我们将加载到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

setVariables方法也接受一个回调作为回应涉及数据完善事件的第二个参数,它接收一个'readyState'对象,您可以检查:

this.props.relay.setVariables({ 
     gifType, 
     }, (readyState)=> { 
     if (!readyState.done) { 
      this.setState({ 
      loading: true 
      }) 
     } else if(readyState.done) { 
      this.setState({ 
      loading: false 
      }) 
     } 
}) 
+0

感谢,这是我脑子里想。有一点需要注意,我注意到,这解决了我每次新加载数据的问题,但是当查询已经加载到以前的状态时,readyState.done的请求中的初始值为true,而不是假(我猜想,因为它假设它已经要求这些数据),这将带来转换之间的滞后。 – user3224271

+0

在启动缓存的情况下,您可以通过稍微调整从'readyState.done'到'readyState.done && this.state.loading'的条件来避免不必要的'setState'调用。 – Igorsvee

0

大问题。在处理特定组件的加载屏幕方面,您拥有的是可行的选项。但是对于每个单独的组件来说,这可能会成为每个负载场景的负担。

如果要提供更通用的解决方案,您可以这样做:您可以在React应用程序中设置一个全局事件系统,根据是否进行调用,将全局状态广播给每个组件。对于您需要的每个组件,您可以从componentDidMount()订阅此全局事件,并取消订阅componentWillUnmount()。只要你的组件看到这个全局状态发生变化,该组件应该调用setState(),这将决定该组件是否应该显示加载场景。

这是学习如何将组件建立一个全球性的事件系统之间的通信一个很好的资源: https://facebook.github.io/react/tips/communicate-between-components.html

您还可以使用Facebook的流量来实现这个还有: https://facebook.github.io/flux/

希望这帮助!