【问题标题】:Relay requests via setVariables通过 setVariables 中继请求
【发布时间】:2016-11-19 02:05:10
【问题描述】:

当通过 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
              }
            }
            }
      }
    `,
  },
});

【问题讨论】:

    标签: graphql relayjs relay graphql-js


    【解决方案1】:

    setVariables 方法还接受一个回调作为第二个参数,该参数响应与数据完成有关的事件,它接收一个您可以检查的 'readyState' 对象:

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

    【讨论】:

    • 谢谢,这就是我的想法。有一件事我注意到了,这解决了我每次新加载数据的问题,但是当对已经加载的先前状态进行查询时,readyState.done 请求中的初始值是 true 而不是false(我猜它假设它已经请求了该数据)这会导致转换之间的延迟。
    • 在准备缓存的情况下,您可以通过将条件从readyState.done 稍微调整为readyState.done &amp;&amp; this.state.loading 来避免不必要的setState 调用。
    【解决方案2】:

    很好的问题。在处理特定组件的加载屏幕方面,您所拥有的是一个可行的选择。但这可能会成为为每个单独组件的每个加载场景实施的负担。

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

    这是学习如何在组件之间进行通信以设置全局事件系统的好资源: https://facebook.github.io/react/tips/communicate-between-components.html

    您也可以使用 Facebook 的 Flux 来实现这一点: https://facebook.github.io/flux/

    希望这会有所帮助!

    【讨论】:

      猜你喜欢
      • 2017-01-11
      • 2017-12-25
      • 1970-01-01
      • 2017-02-05
      • 2015-07-31
      • 2021-09-12
      • 1970-01-01
      • 1970-01-01
      • 2019-03-05
      相关资源
      最近更新 更多