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

Loss of component state when re-rendering sibling component in metal soy. #169

Closed
ethib137 opened this issue Oct 26, 2016 · 4 comments
Closed

Comments

@ethib137
Copy link

Hey @mairatma,

I found an interesting issue when conditionally rendering components.

The situation looks something like this.

{namespace ParentComponent}

/**
 * This renders the component's whole content.
 *
 * @param show
 */
{template .render}
    <div>
        <div><a href="javascript:;" onClick="onClick_">Show Two</a></div>

        {call ComponentOne.render /}

        {call ComponentTwo.render}
            {param show: $show /}
        {/call}
    </div>
{/template}

When the componentOne has some state and the parent component passes a new param to componentTwo, componentOne loses it's state.

For ease of reproducing I created metal component example here: https://github.com/ethib137/metal-bug

To reproduce:

  1. Click "show one"
  2. Click "show two"

Expected Result: "From Component One!" and "From Component Two!" will be displayed.

Actual Result: "From Component One!" is hidden and only "From Component Two!" is displayed.

@mairatma thanks for all your help with metal, I really appreciate all the work you do!

-Evan

@mairatma
Copy link
Contributor

Thanks @ethib137, I'll take a look :)

@mairatma
Copy link
Contributor

I think I know what's going on actually.

When using jsx the separation between public and internal properties is clearer, since we split them into state and props.

When using soy both types of properties are accessed directly via this though. By default, all of them are considered public. That means that, even though you can change them inside the component (like you're doing with label in ComponentOne), you shouldn't do that, as whenever a parent calls it, the public data will be set again, and the ones that are not passed will go back to default values again, just like with props. This label property should be defined as internal instead, so it can keep its value when called via a parent component. To do this, just add the internal: true property to label's config and this problem should go away.

Let me know if that helped :)

@ethib137
Copy link
Author

Thanks for the quick response!

That fixes the issue in my example! I'll check tomorrow to see if it fixes the problem in my component as well.

I'll let you know what I find. :)

@mairatma
Copy link
Contributor

Good to know that helped :)

I'll close this for now, but feel free to reopen if you still get a similar problem in some other situation.

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