[GH-ISSUE #268] State Not Propagating to Child Components #181

Closed
opened 2026-05-05 11:53:19 -06:00 by gitea-mirror · 2 comments
Owner

Originally created by @jcolag on GitHub (Feb 25, 2020).
Original GitHub issue: https://github.com/kusti8/proton-native/issues/268

Describe the bug
When updating the state of a parent component, the change does not flow back to the child.

To Reproduce
Here's a stripped down example, with just a button to trigger a change in the parent (via a callback), which should update its (other) child.

import { App, Button, Text, View, Window } from "proton-native";
import React, { Component } from "react";
export default class Example extends Component {
  constructor(props) {
    super(props);
    this.state = { count: 0 };
  }
  updateName(newName) {
    this.setState({ count: this.state.count + 1 });
  }
  render() {
    return (
      <App>
        <Window style={{ width: 300, height: 100 }}>
          <View>
            <Clicker update={ this.updateName.bind(this) } />
            <ClickTotal count={ this.state.count } />
          </View>
        </Window>
      </App>
    );
  }
}
class Clicker extends Component {
  constructor(props) {
    super(props);
    this.state = { update: props.update };
  }
  render() {
    return (<Button onPress={ this.state.update } title='Increment' />);
  }
}
class ClickTotal extends Component {
  constructor(props) {
    super(props);
    this.state = { count: props.count };
  }
  render() {
    return (<Text>{ this.state.count }</Text>);
  }
}

Expected behavior
In the sample code above, the Text component (in ClickTotal) should increment on every button click. Instead, we can see that Example re-renders and reports this.state.count as increasing, but ClickTotal always sees the count as zero.
Edit to clarify: The child component re-renders when the parent state changes, but always sees the property as its original value, rather than what's being passed in.

Screenshots
Hopefully not necessary, but I can add them later.

Versions:

  • OS: Ubuntu 19.10 (Linux)
  • Version: proton-native@2.0.4
  • Node version: v12.16.0

Additional context
I could obviously add Reflux to the project, but that seems like overkill for such minimal data requirements, if it's not absolutely necessary. The actual project I'm working on is going to need to pass around lists of objects, but the same applies.

Also, v2 is a massive improvement over v1. Thanks!

Originally created by @jcolag on GitHub (Feb 25, 2020). Original GitHub issue: https://github.com/kusti8/proton-native/issues/268 **Describe the bug** When updating the `state` of a parent component, the change does not flow back to the child. **To Reproduce** Here's a stripped down example, with just a button to trigger a change in the parent (via a callback), which should update its (other) child. ```javascript import { App, Button, Text, View, Window } from "proton-native"; import React, { Component } from "react"; export default class Example extends Component { constructor(props) { super(props); this.state = { count: 0 }; } updateName(newName) { this.setState({ count: this.state.count + 1 }); } render() { return ( <App> <Window style={{ width: 300, height: 100 }}> <View> <Clicker update={ this.updateName.bind(this) } /> <ClickTotal count={ this.state.count } /> </View> </Window> </App> ); } } class Clicker extends Component { constructor(props) { super(props); this.state = { update: props.update }; } render() { return (<Button onPress={ this.state.update } title='Increment' />); } } class ClickTotal extends Component { constructor(props) { super(props); this.state = { count: props.count }; } render() { return (<Text>{ this.state.count }</Text>); } } ``` **Expected behavior** In the sample code above, the `Text` component (in `ClickTotal`) should increment on every button click. Instead, we can see that `Example` re-renders and reports `this.state.count` as increasing, but `ClickTotal` always sees the `count` as zero. **Edit to clarify**: The child component re-renders when the parent state changes, *but* always sees the property as its original value, rather than what's being passed in. **Screenshots** Hopefully not necessary, but I can add them later. **Versions:** - OS: Ubuntu 19.10 (Linux) - Version: proton-native@2.0.4 - Node version: v12.16.0 **Additional context** I could obviously add Reflux to the project, but that seems like overkill for such minimal data requirements, if it's not absolutely necessary. The *actual* project I'm working on is going to need to pass around lists of objects, but the same applies. Also, v2 is a massive improvement over v1. Thanks!
gitea-mirror 2026-05-05 11:53:19 -06:00
  • closed this issue
  • added the
    bug
    label
Author
Owner

@kusti8 commented on GitHub (Mar 16, 2020):

This is because in your ClickTotal constructor, you are setting the count into the state of ClickTotal. This is just a number, it has no reference to the other count, so it doesn't get updated. In general, it is better practice to not set your props into the state, but instead just reference them from this. Here's the fixed example:

import { App, Button, Text, View, Window } from "proton-native";
import React, { Component } from "react";

export default class Example extends Component {
  constructor(props) {
    super(props);
    this.state = { count: 0 };
  }
  updateName(newName) {
    this.setState({ count: this.state.count + 1 });
  }
  render() {
    return (
      <App>
        <Window style={{ width: 300, height: 100 }}>
          <View>
            <Clicker update={this.updateName.bind(this)} />
            <ClickTotal count={this.state.count} />
          </View>
        </Window>
      </App>
    );
  }
}
class Clicker extends Component {
  render() {
    return <Button onPress={this.props.update} title="Increment" />;
  }
}
class ClickTotal extends Component {
  render() {
    return <Text>{this.props.count}</Text>;
  }
}
<!-- gh-comment-id:599757346 --> @kusti8 commented on GitHub (Mar 16, 2020): This is because in your `ClickTotal` constructor, you are setting the count into the state of `ClickTotal`. This is just a number, it has no reference to the other count, so it doesn't get updated. In general, it is better practice to not set your props into the state, but instead just reference them from `this`. Here's the fixed example: ```jsx import { App, Button, Text, View, Window } from "proton-native"; import React, { Component } from "react"; export default class Example extends Component { constructor(props) { super(props); this.state = { count: 0 }; } updateName(newName) { this.setState({ count: this.state.count + 1 }); } render() { return ( <App> <Window style={{ width: 300, height: 100 }}> <View> <Clicker update={this.updateName.bind(this)} /> <ClickTotal count={this.state.count} /> </View> </Window> </App> ); } } class Clicker extends Component { render() { return <Button onPress={this.props.update} title="Increment" />; } } class ClickTotal extends Component { render() { return <Text>{this.props.count}</Text>; } } ```
Author
Owner

@jcolag commented on GitHub (Mar 17, 2020):

Ah, thanks! I was hoping this was me doing something stupid.

<!-- gh-comment-id:600051934 --> @jcolag commented on GitHub (Mar 17, 2020): Ah, thanks! I was *hoping* this was me doing something stupid.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: github-starred/proton-native#181
No description provided.