查询完成后如何更新状态?

时间:2020-04-27 15:13:57

标签: reactjs apollo

我有一个页面,该页面在加载时呈现了几个搜索输入和成员列表。当用户更新字段时,查询将重新运行,并根据该输入更新成员列表。我的问题是尝试整合分页。

我正在尝试使用react-infinite-scroll-component模块。 https://www.npmjs.com/package/react-infinite-scroll-component。我正在尝试遵循此处的示例-> https://codesandbox.io/s/yk7637p62z?file=/src/index.js:855-998

我的直觉是我需要用成员列表更新初始状态。我怎样才能做到这一点?我以为onCompleted可能会起作用,但是还没有办法解决。

import React, { Component } from "react";
import { Query } from "react-apollo";
import gql from "graphql-tag";
import styled from "styled-components";
import InfiniteScroll from "react-infinite-scroll-component";
import { SearchStyles } from "./styles/DropDown";
import Divider from "../components/styles/Divider";
import Member from "./Member";
import Form from "./styles/Form";

const SEARCH_BASIC_QUERY = gql`
  query SEARCH_BASIC_QUERY($iam: String, $ageLow: Int) {
    members(where: { iam_starts_with: $iam, ageLow_lte: $ageLow }) {
      id
      firstName
      image1
      iam
      ageLow
    }
  }
`;

const MembersList = styled.div`
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-gap: 60px;
  margin: 0 auto;
  max-width: ${props => props.theme.maxWidth};
`;

const FormSectionWrap = styled.div`
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  grid-gap: 0px;
  margin-bottom: 72px;
`;

const FormSectionTitle = styled.div`
  grid-column: 1 / 5;
  h4 {
    margin-bottom: 16px;
    margin-top: 0;
    color: ${props => props.theme.grey1};
    font-size: 400;
    font-weight: 600;
  }
  div {
    margin: 0;
  }
  p {
    color: ${props => props.theme.grey4};
  }
`;

const FormSectionFields = styled.div`
  grid-column: 6 / 11;
`;

class BasicSearch extends Component {
  state = {
    // members: Array.from({ length: 4 }),
    members: [],
    items: Array.from({ length: 20 })
  };

  handleChange = e => {
    const { name, type, value } = e.target;
    const val = type === "number" ? parseFloat(value) : value;

    this.setState({ [name]: val });
  };

  fetchMoreData = () => {
    // a fake async api call like which sends
    // 20 more records in 1.5 secs
    setTimeout(() => {
      this.setState({
        items: data.members.concat(Array.from({ length: 20 }))
      });
    }, 1500);
  };

  render() {
    return (
      <SearchStyles>
        <Form>
          <fieldset>
            <FormSectionWrap>
              <FormSectionTitle>
                <h4>Basic Search</h4>
                <Divider></Divider>
                <p>
                  Quam porttitor aenean suspendisse duis neque, ullamcorper
                  pulvinar id feugiat pulvinar duis
                </p>
              </FormSectionTitle>
              <FormSectionFields>
                <label htmlFor="iam">
                  Seeking A
                  <select
                    type="text"
                    id="iam"
                    name="iam"
                    placeholder=""
                    onChange={this.handleChange}
                  >
                    <option selected disabled hidden value="">
                      ---
                    </option>
                    <option>Female</option>
                    <option>Male</option>
                  </select>
                </label>

                <label htmlFor="ageLow">
                  Between ages
                  <select
                    type="number"
                    id="ageLow"
                    name="ageLow"
                    placeholder=""
                    onChange={this.handleChange}
                  >
                    <option selected disabled hidden value="">
                      ---
                    </option>
                    <option>18</option>
                    <option>25</option>
                    <option>35</option>
                    <option>45</option>
                    <option>55</option>
                    <option>65</option>
                  </select>
                </label>
              </FormSectionFields>
            </FormSectionWrap>
          </fieldset>
        </Form>

        <Query
          query={SEARCH_BASIC_QUERY}
          variables={{
            ...this.state
          }}
        >
          {({ data, loading }) => {
            if (loading) return <p>Loading...</p>;

            if (!data.members.length)
              return (
                <p>
                  No Members Yet! Do a search above. *Note* We should build out
                  this empty state. Opportunity to show some personality.
                </p>
              );

            return (
              <div>
                <InfiniteScroll
                  dataLength={this.state.items.length} //This is important field to render the next data
                  next={this.fetchMoreData}
                  hasMore={true}
                  loader={<h4>Loading...</h4>}
                  endMessage={
                    <p style={{ textAlign: "center" }}>
                      <b>Yay! You have seen it all</b>
                    </p>
                  }
                >
                  {/* Renders list of members */}
                  {data.members.map(member => (
                    <Member member={member} key={member.id}></Member>
                  ))}
                  }{/* Code from infinite scroll example */}
                  {this.state.items.map((i, index) => (
                    <div key={index}>div - #{index}</div>
                  ))}
                </InfiniteScroll>

                <MembersList>
                  {/* {data.members.map(member => (
                    <Member member={member} key={member.id}></Member>
                  ))} */}
                </MembersList>
              </div>
            );
          }}
        </Query>
      </SearchStyles>
    );
  }
}

export default BasicSearch;

0 个答案:

没有答案