Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot change meta data dynamically client side #87

Closed
AmrARaouf opened this issue Dec 24, 2015 · 3 comments
Closed

Cannot change meta data dynamically client side #87

AmrARaouf opened this issue Dec 24, 2015 · 3 comments

Comments

@AmrARaouf
Copy link

I cannot seem to change the meta data from the client side. When I change the "meta" state attribute, the change seems only be queued. It is only activated when I make another change to the dom, like changing the title for example.

For instance, if my state changing function looks like this:

var meta = [{"name": "keywords", "content": "default"}, {"charset": "UTF-8"}];     
foo(bar) {
  var newMeta = this.state.meta;
  newMeta[0].content = bar;
  this.setState({
    meta: newMeta
  })
},

And my "Helmet" looks like this:

<Helmet meta = {this.state.meta}
    title = {this.state.title} />

When foo(bar) is called, "default" never changes to bar.

However if my function looks like this:

foo(bar) {
  var newMeta = this.state.meta;
  newMeta[0].content = bar;
  this.setState({

    // <-- CHANGE
    title: bar,
    // -->

    meta: newMeta
  })
},

Then both the title and the meta tag change successfully.

@cwelch5
Copy link
Contributor

cwelch5 commented Jan 4, 2016

When changing the title, this shouldn't have any bearing on whether meta changes or not. I need to do a quick test to double-check.

@AmrARaouf
Copy link
Author

Any luck?

@cwelch5
Copy link
Contributor

cwelch5 commented Jan 21, 2016

@AmrARaouf
Thanks for your patience.

The reason this fails is because the shouldComponentUpdate check in Helmet returns false when just passing the meta, which causes the component not to re-render. You would get the same result if you passed an unchanged title value.

I did some debugging and found that in your scenario, when Helmet checks this.props and nextProps and compares them, the value is already changed:

[{"name": "keywords", "content": "bar"}, {"charset": "UTF-8"}]
[{"name": "keywords", "content": "bar"}, {"charset": "UTF-8"}]

And this is a result of manipulating the state directly in your foo function. You should never manipulate state directly, but always create new variables, so instead of

  var newMeta = this.state.meta;
  newMeta[0].content = bar;

try

  var newMeta = [
       {
             ...this.state.meta[0]
       }
  ];
  newMeta[0].content = bar;

With the spread operator we can make a new object with same values and then manipulate that new object to pass to Helmet.

@cwelch5 cwelch5 closed this as completed Jan 21, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants