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

Is bug? is bugfix? :: affecting ember-source 5.6+ with false-negatives w/ backtracking re-render assertions #1629

Open
NullVoxPopuli opened this issue Oct 14, 2024 · 5 comments

Comments

@NullVoxPopuli
Copy link
Contributor

NullVoxPopuli commented Oct 14, 2024

Reproduction in Limber (locally running on port 4301)

Notes:


Examples of real code that "broke" in ember 5.6+ (which, imo, is legit problematic, and should be migrated away from)

  • creating records in class properties
    @tracked createdModel = this.store.createRecord('model-name');
    this is problematic because createRecord interacts with "Live arrays", which have previously been used on the pages (imagine a table view with a navigatable create modal).
    • What should happen instead: folks should only call createRecord as the result of a user action, such as submitting a form.
  • Setting data outside of the current context / component as a result of construction
    constructor(owner, args) {
      super(owner, args);
      
      if (this.args.options.length === 1) {
        this.setType(this.args.options[0]);
      }
    }
    
    selectedRelatedData = this.args.relatedData;
    
    setType = (option) => {
      // option is tracked
      this.selectedRelatedData.option = option;
    }
    • What should happen instead: is that selectedRelatedData should be derived, as should the type, potentially using localCopy from tracked-toolbox if local state forking needing.
      for example:
      get _type() {
        if (this.args.options.length === 1) {
          return this.args.options[0];
        }
      }
      
      @localCopy('_type') type;
  • making requests on reactive data in the constructor
    constructor() {
      super(...arguments);
      this.setup();
    }
    
    setup = () => {
      this.args.model.data?.reload();
    }
    This has the same problem as above, where the data can be a part of a live array (or other structure) elsewhere on the page.
    • What to do instead: fetch data earlier (such as in the model hook), or wait to fetch until a user interaction.
  • Changing the route upon construction of a component
    constructor() {
      super(...arguments);
      
      this.router.transitionTo(`route.name.here`);
    }
    • What to do instead: either don't even have this component in the first place, or have whatever is wanting to render this component just do the transition instead (for example, as the result of a user interaction)

Examples of real code that "broke" in ember 5.6+ which maybe shouldn't have

... trying to find reproductions ...

@evoactivity
Copy link

@krisselden
Copy link
Contributor

krisselden commented Oct 16, 2024

@NullVoxPopuli this is as designed, you are reading and writing to a tracked property in one render pass. This makes it so that there are potentially 2 versions of the same tracked property. There isn't any way for it to know you are not using the prior version you read.

There are also simple refactors to avoid it. Most of this is because you want a tracked property for local changes based on derived state. You can create a new instance with a tracked property and cache it to the source tracked. Like tracked url to derived class State tracked isLoading = true, cached on url ==. This lets you set isLoading to false when it finishes and if the url changes, the cache invalidates and you get a new State for the new url initialized to isLoading = true.

@krisselden
Copy link
Contributor

This issue comes up because the old assertion was tied to a chain of state tied all the way into the rendering. As things move to tracked, rendering is basically cached on the source versions of tracked and doesn't book keep all the way to rendering. so the more systems that refactor to rely on autotracking the more you hit cases where people are reading during render and even if they aren't using that read value in any derived state, autotracking can't assume that.

NullVoxPopuli added a commit that referenced this issue Oct 16, 2024
@NullVoxPopuli
Copy link
Contributor Author

I think the reproductions I have are not reproductions, because they fail on 0.84.3 as well.

@NullVoxPopuli NullVoxPopuli changed the title Fix major issue affecting ember-source 5.6+ with false-negatives w/ backtracking re-render assertions Is bug? is bugfix? :: affecting ember-source 5.6+ with false-negatives w/ backtracking re-render assertions Oct 16, 2024
@boris-petrov
Copy link
Contributor

I'm not sure I understand correctly what you're talking about here but could this also be what you're looking for as a reproduction?

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

4 participants