问题
I am in the process of learning graphql and react-apollo. I have set up a search query in my code. I am unsure how to pass a variable from my code (i.e. this.state.search
) to my grapnql call.
I have looked at many answers including this one, but it seems a bit different.
The docs also don't seem to give any guidance on how to use state as the variable.
My code is below.
Can anyone advise how to connect both of these?
import React, { Component} from 'react'
import { graphql } from 'react-apollo'
import gql from 'graphql-tag'
class Search extends Component {
constructor(props) {
super(props)
this.state = {
search: ''
}
}
updateSearch = (e) => {
this.setState({
search: e.target.value
})
}
submitSearch = (e) => {
e.preventDefault()
console.log(this.state)
}
render() {
const { search } = this.state;
return (
<form onSubmit={ this.submitSearch }>
<input
type='text'
onChange={ this.updateSearch }
value={ search }
placeholder='Search'
/>
</form>
)
}
}
export default graphql(gql`
{
search(query: "Manchester", type: TEAM) {
name
}
}`)(Search)
回答1:
You'll want to split this up into at least two components. One that holds the state of what the user searched, then another that actually does the querying by getting a prop. Additionally you can have the apollo higher order component skip the query if the form was submitted without entering something.
import React, {Component} from 'react'
import {graphql} from 'react-apollo'
import gql from 'graphql-tag'
class Results extends Component {
render() {
// apollo provides results under the data prop
const {data} = this.props;
return <h1>{data.search.namej}</h1>
}
}
const ResultsWithQuery = graphql(gql`
query FindTeam($query: String!) {
search(query: $query, type: TEAM) {
name
}
}
`, {skip: (ownProps) => !ownProps.query})(Results);
export class Search extends Component {
constructor(props) {
super(props)
this.state = {
search: ''
}
}
updateSearch = (e) => {
this.setState({
search: e.target.value
})
}
submitSearch = (e) => {
e.preventDefault()
console.log(this.state)
}
render() {
const {search} = this.state;
return (
<div>
<form onSubmit={this.submitSearch}>
<input
type='text'
onChange={this.updateSearch}
value={search}
placeholder='Search'
/>
<ResultsWithQuery query={search} />
</form>
</div>
)
}
}
* UPDATE * Now that react-apollo@2.1 has been released there is an alternative way using render props.
https://www.apollographql.com/docs/react/essentials/get-started.html#request
This simplifies the number of components you need in this case.
import React, { Component} from 'react'
import { Query } from 'react-apollo'
import gql from 'graphql-tag'
const SearchQuery = gql`
query FindTeam($query: String!) {
search(query: $query, type: TEAM) {
name
}
}
`;
export default class Search extends Component {
constructor(props) {
super(props)
this.state = {
search: ''
}
}
updateSearch = (e) => {
this.setState({
search: e.target.value
})
}
submitSearch = (e) => {
e.preventDefault()
console.log(this.state)
}
render() {
const { search } = this.state;
return (
<form onSubmit={ this.submitSearch }>
<input
type='text'
onChange={ this.updateSearch }
value={ search }
placeholder='Search'
/>
<Query query={SearchQuery} skip={!search} variables={{query: search}}>
{({loading, error, data}) => {
if (loading) return null;
if (error) throw err;
return <h1>{data.search.namej}</h1>
}}
</Query>
</form>
)
}
}
来源:https://stackoverflow.com/questions/49238490/pass-variable-from-input-to-graphql-search-call