当前位置: 动力学知识库 > 问答 > 编程问答 >

graphql - Relay requests via setVariables

问题描述:

when a request is made via setVariables is there a way to take account of the local state in-between async requests i.e. to implement loading indicator ?

an illustration making requests to 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

})

}

this won't track the loading state and loading will pass on to false immediately while the async change to the view will have lag.

if we move loading into setVariables is there any way to track the response ? in the root container there is the ability to track response via

 renderLoading={function() {

return <div>Loading...</div>;

}}

is there any similar method for Relay.createContainer

is it bad practice to use setVariables to navigate through data sets ?

full code

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

}

}

}

}

`,

},

});

网友答案:

setVariables method also accepts a callback as the 2nd argument which responds to the events involved with the data fulfillment and it receives a 'readyState' object that you can inspect:

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

Great question. What you have is a viable option in terms of dealing with loading screens for a particular component. But that can become a burden to implement for every loading scenario for each individual component.

Here's what you can do instead if to provide a more generic solution: You can set up a global event system in your React app that will broadcast a global state to each component based on whether or not a call is being made. And for each component that you need this for, you can subscribe to this global event from componentDidMount() and unsubscribe with componentWillUnmount(). As soon as your component sees a change in this global state, that component should call setState(), which will determine whether or not that component should display a loading scene or not.

This is a good resource to learn how to communicate between components to set up a global event system: https://facebook.github.io/react/tips/communicate-between-components.html

You can also use Facebook's Flux to implement this as well: https://facebook.github.io/flux/

Hope this helps!

分享给朋友:
您可能感兴趣的文章:
随机阅读: