【问题标题】:React: Data not showing until page refreshes反应:直到页面刷新数据才显示
【发布时间】:2019-07-12 02:26:03
【问题描述】:

我目前正在使用 React 和 GraphQL 构建一个简单的 CRUD 工作流。在我创建了一个对象(在这种情况下是一个article,它只有一个idtitledescription。)后,我导航回一个Index 页面,其中显示了所有当前创建的文章。我的问题是创建文章后,在我刷新页面之前,索引页面不会显示创建的文章。我正在使用apollo 查询graphql api 并禁用了缓存,所以我不确定为什么数据没有显示。我在我的ArticlesIndexcomponentDidMount 函数中设置了断点,并确保它正在执行,并且在执行时,数据库确实包含新添加的article

当执行检索所有文章的客户端查询时,我的服务器端实际上甚至从未被命中。我不确定是什么在缓存这些数据,以及为什么它没有按预期从服务器检索。

我的ArticlesCreate 组件插入新记录并重定向回ArticlesIndex 组件,如下所示:

handleSubmit(event) {  
    event.preventDefault();  
    const { client } = this.props;

    var article = {
      "article": {
        "title": this.state.title,
        "description": this.state.description
      }
    };

    client
    .mutate({ mutation: CREATE_EDIT_ARTICLE, 
      variables: article })
    .then(({ data: { articles } }) => {
        this.props.history.push("/articles");  
    })
    .catch(err => {
        console.log("err", err);
    });

  }
}

然后我的ArticlesIndex 组件从数据库中检索所有文章,如下所示:

componentDidMount = () => {
    const { client } = this.props; //client is an ApolloClient
    client
    .query({ query: GET_ARTICLES })
    .then(({ data: { articles } }) => {
        if (articles) {
          this.setState({ loading: false, articles: articles });
        }
    })
    .catch(err => {
        console.log("err", err);
    });
};

并且我已将 ApolloClient 设置为不缓存数据,就像我的 App.js 中一样,如下所示:

const defaultApolloOptions = {
  watchQuery: {
    fetchPolicy: 'network-only',
    errorPolicy: 'ignore',
  },
  query: {
    fetchPolicy: 'network-only',
    errorPolicy: 'all',
  },
}

export default class App extends Component {
  displayName = App.name;

  client = new ApolloClient({
    uri: "https://localhost:44360/graphql",
    cache: new InMemoryCache(),
    defaultOptions: defaultApolloOptions
  });

  //...render method, route definitions, etc
}

为什么会发生这种情况,我该如何解决?

【问题讨论】:

  • 假设articles 是一个数组this.setState({ loading: false, articles: [...articles] });?还是需要解析的JSON?
  • articles 确实是一个数组,但是设置状态工作正常。据我所知,问题是articlescomponentDidMount 中我的查询的.then 回调中包含陈旧数据(在执行创建调用之前)
  • 你如何导航回来?浏览器返回按钮或调用您的索引组件?
  • this.props.history.push("/articles"); ArticlesCreate 组件中(该路由用于ArticlesIndex 组件

标签: reactjs graphql apollo react-apollo apollo-client


【解决方案1】:

我可以看到您正在获取数据并在初始安装时设置组件状态。很可能当您重定向它时,它不会触发 componentDidMount 生命周期钩子,因为它已经挂载,如果这是问题,请尝试使用 componentDidUpdate 生命周期钩子,以便您的组件知道有更新并重新设置数据。

【讨论】:

  • 他正在设置状态,因此应该调用渲染。您应该从componentDidMount 而不是componentDidUpdate 调用后端
  • 我可以确认 componentDidMount 在我的创建组件重定向回我的索引组件后被调用。然而,由于某种原因,查询似乎并没有真正执行并且它正在处理陈旧的数据。 (回调中的articles 不是最新的,但这段代码正在执行)
【解决方案2】:

看起来这是ApolloBoost 不支持defaultOptions 的问题,如in this github issue 所述。为了解决我更改的问题:

const defaultApolloOptions = {
  watchQuery: {
    fetchPolicy: 'network-only',
    errorPolicy: 'ignore',
  },
  query: {
    fetchPolicy: 'network-only',
    errorPolicy: 'all',
  },
}

export default class App extends Component {
  displayName = App.name;

  client = new ApolloClient({
    uri: "https://localhost:44360/graphql",
    cache: new InMemoryCache(),
    defaultOptions: defaultApolloOptions
  });

  //...render method, route definitions, etc
}

收件人:

const client = new ApolloClient({
  uri: "https://localhost:44360/graphql"
});

client.defaultOptions = {
  watchQuery: {
    fetchPolicy: 'network-only',
    errorPolicy: 'ignore',
  },
  query: {
    fetchPolicy: 'network-only',
    errorPolicy: 'all',
  },
};

export default class App extends Component {
    //....
}

【讨论】:

    猜你喜欢
    • 2022-01-21
    • 2021-09-24
    • 2014-11-13
    • 1970-01-01
    • 1970-01-01
    • 2019-11-22
    • 2016-04-06
    • 2021-09-23
    • 1970-01-01
    相关资源
    最近更新 更多