Как установитьState () в React / Apollo с помощью graphQL

Я пытаюсь установитьState () на результат запроса, который у меня есть из graphQL, но мне трудно понять, как это сделать, потому что он всегда будет загружаться или используется только из реквизита. Я сначала установил состояние

constructor (props) {
        super(props);
        this.state = { data: [] };

Тогда у меня есть этот запрос

const AllParams = gql`
    query AllParamsQuery {
        params {
            id,
            param,
            input
        }
    }`

И когда он вернется, я могу получить к нему доступ с помощью this.props.AllParamsQuery.params

Как и когда мне this.setState({ data: this.props.AllParamsQuery.params }) не возвращать {data: undefined} ?

Я не нашел способа заставить его ждать, пока он undefined AKA loading: true затем setState. Я пробовал componentDidMount() и componentWillReceiveProps(), включая async function(){...await...}, но безуспешно, вероятно, я делаю это неправильно. Кто-нибудь знает, как это сделать правильно или есть пример?

РЕДАКТИРОВАТЬ + Ответ: вы не должны устанавливать состояние, просто оставляйте его в props. Ознакомьтесь с этой ссылкой: «Почему установка props в качестве состояния в react.js - это кощунство» http://johnnyji.me/react/2015/06/26/why-setting-props-as-state-in-react-is-blasphemy.html Проблема с обновлением реквизита - это еще одна проблема, но в этом руководстве по созданию приложения можно найти несколько отличных примеров: https://www.howtographql.com/react-apollo/8-subscriptions/


person Kevin Danikowski    schedule 27.09.2017    source источник
comment
Неработающей ссылке. Вот снимок машины обратного пути https://web.archive.org/web/20200125010920/http://johnnyji.me/react/2015/06/26/why-setting-props-as-state-in-react-is-blasphemy.html   -  person Grimtech    schedule 18.09.2020


Ответы (3)


Простое решение - разделить компоненты запросов Apollo и компоненты React с отслеживанием состояния. Исходя из Redux, нет ничего необычного в преобразовании входящих реквизитов для состояния локального компонента с помощью mapStateToProps и componentWillReceiveProps. Однако этот образец запутывается с <Query /> Аполлона.

Так что просто создайте отдельный компонент, который извлекает данные:

...

export class WidgetsContainer extends Component {
  render (
    <Query query={GET_WIDGETS}>
      {({ loading, error, data }) => {
        if (loading) return <Loader active inline="centered" />;

        const { widgets } = data;
        return (
          <Widgets widgets={widgets} />
        )
      }}
    </Query>
  )
}

И теперь компоненты Widgets могут использовать setState как обычно:

...
export class Widgets extends Component {
  ...
  constructor(props) {
    super()

    const { widgets } = props;
    this.state = {
      filteredWidgets: widgets
    };
  }

  filterWidget = e => {
    // some filtering logic
    this.setState({ filteredWidgets });
  }

  render() {
    const { filteredWidgets } = this.state;
    return (
      <div>
        <input type="text" onChange={this.filterWidgets} />
        {filteredWidgets.count}
      </div>
    )
  }
}
person Connor    schedule 05.03.2019

В чем причина установки состояния? Имейте в виду, что Apollo Client использует внутреннее хранилище redux для управления запросами. Если вы пытаетесь запустить повторный рендеринг в зависимости от того, когда что-то меняется в запросе, вам следует использовать refetchQueries (). Если вам абсолютно необходимо сохранить его в локальном состоянии, я предполагаю, что вы, вероятно, можете сравнить nextProps в componentWillReceiveProps, чтобы определить, когда загрузка (значение, которое возвращается, когда вы выполняете запрос из клиента apollo) изменилось, а затем обновите свое состояние.

person Alex K    schedule 28.09.2017
comment
Согласился, я обнаружил, что нет смысла использовать состояние и оставлять его в props! - person Kevin Danikowski; 29.09.2017
comment
это причина: вот почему установка props как состояния в react.js - это кощунство johnnyji.me/react/2015/06/26/ - person Kevin Danikowski; 29.09.2017
comment
Круто, с Apollo все очень просто! - person Alex K; 29.09.2017

У меня была аналогичная проблема (хотя это происходило по совершенно другой причине). Мое состояние продолжало становиться неопределенным. Я смог решить эту проблему с помощью промежуточного программного обеспечения React. Это позволило легко избежать этой проблемы. В итоге я использовал супергент.

http://www.sohamkamani.com/blog/2016/06/05/redux-apis/

person Eric    schedule 28.09.2017
comment
спасибо, Эрик, я считаю, что использовать setstate было действительно плохо. См .: Вот почему установка props как состояния в react.js - это кощунство johnnyji.me/react/2015/06/26/ - person Kevin Danikowski; 29.09.2017
comment
Ах. Да, если вам просто нужны неизменяемые данные, забудьте о настройке props в качестве состояния. - person Eric; 29.09.2017