1

I'm creating a blog, using React. I uploaded some parts: https://codesandbox.io/s/youthful-bush-z3cce

There is one note on the main page and a list of other notes. When I click on some link of these notes, it opens and I can see another post. But if I try to click again on another post, it doesn't reload, though it changes the url.

Xenia
  • 85
  • 1
  • 8
  • 1
    You've just shared your API key with the world. Are you sure that's ok? – apokryfos Jan 04 '20 at 10:40
  • @apokryfos I think you're right, the API key shouldn't be shared as mentioned in the [FAQ](https://www.contentful.com/faq/personal-access-tokens/) (last question - Should I secure these tokens? How?). But the proposed env. handling is just working for a static site (e.g. Gatbsy blog). Is there anywhere a post how to handle it with a client side app? – AWolf Jan 04 '20 at 11:16
  • You can't really. You need some sort of a server-side "controller" to act as a wrapper for requests made using your key – apokryfos Jan 04 '20 at 11:18
  • @xenia which key is in the Sandbox? Is it a delivery key or a personal access key? If it's a personal access key I think you should goto `Settings/API keys` and revoke the key. If it's a delivery key I think it's OK to keep it active as it is read-only. There is a [SO question](https://stackoverflow.com/questions/36134591/hiding-contentful-space-id-and-access-token-client-side-javascript-file) about token handling. – AWolf Jan 04 '20 at 11:28
  • Thank you very much! I will be more careful next time. – Xenia Jan 04 '20 at 11:54
  • @xenia I wrote a [blog post](https://blog.alexanderwolf.tech/how-to-use-contentful-keys-in-a-client-side-app) about the keys with a React demo app. Could be interesting. I think I'll also write a post about how it could be secured with a lambda. But for a blog with read-only of content, it's OK to use the delivery token directly from React. – AWolf Jan 09 '20 at 19:47

1 Answers1

1

It's because you have the same component rendering your posts. Your componentDidMount runs only once and it is responsible for calling your api. You need to get the api logic in a different function and call it again in componentDidUpdate.

I have done it in a codesanbox repo - https://codesandbox.io/s/musing-grass-sxokl

 componentDidMount() {
    if (!this.props.match) {
      return;
    } else {
      this.callApi();
    }
  }

  componentDidUpdate() {
    this.callApi();
  }

  callApi = () => {
    client
      .getEntries({
        content_type: "blogPost",
        "fields.slug": this.props.match.params.slug
      })
      .then(response => {
        console.log(response);
        this.setState(
          {
            content: response.items[0].fields.content,
            title: response.items[0].fields.title,
            date: response.items[0].fields.date,
            country: response.items[0].fields.country
          },
          () => console.log(this.state)
        );
      });
  };

Hope this helps you.

Atin Singh
  • 3,624
  • 2
  • 18
  • 25
  • Of course you should choose a better name for your api logic funtion instead of something so straighforward and vague. :) – Atin Singh Jan 04 '20 at 10:43
  • 1
    Yes, `componentDidUpdate` should do the trick here. But also check that the props changed in the `didUpdate` method, so you're not calling the api too often. I've created a Sandbox [here](https://codesandbox.io/s/musing-banach-shwdx). I also improved some smaller parts of the component. – AWolf Jan 04 '20 at 11:00
  • 1
    @AWolf You are right. I totally forgot about it. Thanks. :) – Atin Singh Jan 04 '20 at 11:21