Я использую ApolloProvider в качестве HOC для получения данных с сервера и Query из 'react-apollo' для отображения данных на страницах и в компонентах.
А вот вопрос. <Query /> визуализирует данные непосредственно в такие элементы, как <input />, без использования состояния компонента. Но что, если я хочу изменить значение <input /> с помощью функции onChange(), где мне хранить новые значения?
Можно ли получить данные с помощью Apollo в componentDidMount(), сохранить их, а затем передать в render()?
Вот фиктивный код, который у меня есть, просто для примера:
const USER = id => gql`
{
user(id: "${id}") {
_id
name
surname
email
}
}
`;
render() {
const { id } = this.props;
return (
<Query query = {USER(id)}>
{({ loading, error, data }) => {
if (loading) return <p>Loading...</p>;
if (error) return <p>Error:(</p>;
const { user } = data;
return (
<div>
<input type = "text" value = {user.name} />
<input type = "text" value = {user.surname} />
<input type = "text" value = {user.email} />
</div>
);
}}
</Query>
);
}
Я хочу добавить функцию onChange() к этим входам, а затем выполнить мутацию GraphQL.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вы можете обернуть Mutation вокруг вашего запроса (или наоборот, это ничего не изменит). А затем привяжите функции onChange ваших входов к действию Mutation.
<Mutation mutation = {UPLOAD_FILE}>
{action =>
<Query query = {USER(id)}>
{({ loading, error, data }) => {
if (loading) return <p>Loading...</p>;
if (error) return <p>Error:(</p>;
const { user } = data;
return (
<div>
<input type = "text" value = {user.name} onChange = {ev => action({ variables: { newText: ev.target.value } })} />
<input type = "text" value = {user.surname} onChange = {ev => action({ variables: { newText: ev.target.value } })} />
<input type = "text" value = {user.email} onChange = {ev => action({ variables: { newText: ev.target.value } })} />
</div>
);
}}
</Query>
}
</Mutation>
Вы также можете вывести логику из вашего JSX, привязав результат к функции в вашем классе:
handleInputChange = (action, type) => ev => {
action({ variables: { [type]: ev.target.value } })
}
<Mutation mutation = {UPLOAD_FILE}>
{action =>
<Query query = {USER(id)}>
{({ loading, error, data }) => {
if (loading) return <p>Loading...</p>;
if (error) return <p>Error:(</p>;
const { user } = data;
return (
<div>
<input type = "text" value = {user.name} onChange = {this.handleInputChange(action, 'name')} />
<input type = "text" value = {user.surname} onChange = {this.handleInputChange(action, 'surname')} />
<input type = "text" value = {user.email} onChange = {this.handleInputChange(action, 'email')} />
</div>
);
}}
</Query>
}
</Mutation>
Что ж, в моем втором примере вы можете проверить правильность данного ввода в функции handleInputChange, так как все изменения будут проходить мимо него. Вы также можете использовать то, что вернет мутация, чтобы установить свое состояние и контролировать свои входные данные. Вам нужен пример?
Спасибо за подсказку, попробую на вашем примере. Однако довольно странно, что состояние не используется для хранения значений, потому что это полезно в случаях, когда вам нужно добавить проверку для входных данных (например, электронной почты) и после проверки изменить с помощью кнопки сохранения