question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[v4] Strange nested component redraw bug after updating parent state

See original GitHub issue

Bug Report

Context

Take a page containing the following…

<h1>Hello!</h1>
<session-panel />

…with a session-panel component defined in a singe index.marko file…

components/session-panel/index.marko
<script>
module.exports = {
  onInput(attrs) {
    this.state = { passwordGrade: 'bad' }
  },
  setGrade(newGrade) {
    console.log("Setting", newGrade)
    this.state.passwordGrade = newGrade
  }
}
</script>

<form class="session-panel" method="POST">

  <h3>Sign Up for an Account:</h3>
  <password-picker on-grade('setGrade') />
  <button type="submit" disabled=( state.passwordGrade == 'bad' )>Sign Up</button>

</form>

…and the following component for password-picker

components/password-picker/index.marko
<script>
module.exports = {
  onInput(attrs) {
    this.state = { password: '', grade: 'bad' }
  },
  setPassword(e) {
    this.state.password = e.target.value
    if (this.state.password.length >= 3) {
      this.state.grade = 'good' // joke
    }
    else {
      this.state.grade = 'bad'
    }
    console.log("Emitting", this.state.grade)
    this.emit('grade', this.state.grade)
  },
}
</script>

<div class="password-picker">

  <input type="password" name="password" value=state.password
         on-input('setPassword') placeholder="Please enter a password" />

  <div class="grade">
    Password strength:
    <b if(state.grade == 'good')>Good!</b>
    <b else>Bad password. Bad!</b>
  </div>
</div>

Expected Behavior

Typing three characters into the input box should enable the submit button.

Actual Behavior

Typing three characters into the input box resets and re-initializes the password-picker component. Typing another character also does not show up. It does enable the submit button, though.

If you remove the this.state.passwordGrade = newGrade line, the password-picker component no longer re-initializes.

Additional Info

Your Environment

  • Version used: v4.0.0-rc.8
  • Environment name and version: Chrome 54
  • Operating System and version: OS X

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Comments:5 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
mlrawlingscommented, Jan 26, 2017

@mindeavor I wonder if there could be value in making this work using constructor:

class {
    constructor(input, out) {
        this.state = {
            count: input.startCount
        };
    }
    onInput(input, out) {
        this.state.color = input.color;
    }
    increment() {
        this.state.count++;
    }
}

<div>${state.count}</div>
<button on-click('increment')>+</button>
<counter start-count=0 color="#ccc"/>

In this hypothetical example, both constructor and onInput would be called when creating the component, yielding an initial state of { count:0, color:'#ccc' }.

Changing the value of the color attribute would only call onInput and therefore would not clobber the existing count.

0reactions
gilbertcommented, Jan 26, 2017

@mlrawlings Yes, using constructor makes a lot of sense 😃 How would constructor run with respect to server/client side rendering?

Read more comments on GitHub >

github_iconTop Results From Across the Web

New bug with nested components / variants has broken ...
The nested component has an instance swap property and the instance has multiple variants. To use this, I create an instance of shell...
Read more >
React: why child component doesn't update when prop changes
You need to set some state to the parent then rerender the child on parent change state. ... When create React components from...
Read more >
When does React re-render components? - Felix Gerschau
As a result, the child components only update when the parent component's state changes with one of those functions.
Read more >
The mystery of React Element, children, parents and re-renders
Now, we know that React components re-render themselves and all their children when the state is updated. In this case, on every mouse...
Read more >
Angular OnPush Change Detection - Avoid Common Pitfalls
To avoid this issue, we simply need to either avoid mutating objects directly or use an immutability library to freeze the view model...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found