Состояние GraphQL и ReactJS

Я использую 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.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
0
49
1

Ответы 1

Вы можете обернуть 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>

Спасибо за подсказку, попробую на вашем примере. Однако довольно странно, что состояние не используется для хранения значений, потому что это полезно в случаях, когда вам нужно добавить проверку для входных данных (например, электронной почты) и после проверки изменить с помощью кнопки сохранения

Sgt Maddonut 06.02.2019 14:53

Что ж, в моем втором примере вы можете проверить правильность данного ввода в функции handleInputChange, так как все изменения будут проходить мимо него. Вы также можете использовать то, что вернет мутация, чтобы установить свое состояние и контролировать свои входные данные. Вам нужен пример?

Treycos 06.02.2019 14:56

Другие вопросы по теме