1

I'm dynamically creating components in create-react-native-app. Everything is working fine using the expo app for testing in Development mode using npm start, and connecting with an android phone.

If I switch it to Production mode, or try to build the apk as a Standalone app the object is not created on the Button press.

This is my first project with React Native, and I don't know how to debug this. I've also been unable to find any information about what the differences between these two modes might be that would lead to this.

Here the relevant code:

export default class App extends React.Component {
  constructor(props) {
    super(props);
    this.updateState = this.updateState.bind(this);
    this.state = {
      knobs: [],
      key: 1
    }
  }

  add = () => {
    let key = this.state.key + 1
    let knob = (<Object key={key} updateState={this.updateState}/>);
    let knobs = this.state.knobs;
    knobs.push(knob);
    this.setState({knobs: knobs, key: key})
  }

  render = () => {
    return ([<View>
      {this.state.knobs}
      <Button onPress={() => this.add()} title='add thing'/>
    </View>
      ]);
  }
}
tracey
  • 111
  • 1
  • 4

2 Answers2

1

I'm not sure what causes the issue since we don't have any sort of error message but below snippet of code might help.

When you assign a variable like below;

let knobs = this.state.knobs;

You are not creating a new variable, you are creating a reference to the original property. Because of this you mutate the state. This might cause the issue.

For setting new state values related to current state values you can use functional setState syntax and destructuring assignment. It is a little bit more easy to use and a little bit more easy to read.

add = () => {
  this.setState((prevState) => {
    const { knobs, key } = prevState; // deconstruct array and key from state
    const newKnob = (<Object key={(key + 1)} updateState={this.updateState}/>);
    knobs.push(newKnob); // push new item to array
    return { knobs, key: (key + 1) } //return new state values
  });
}
bennygenel
  • 23,896
  • 6
  • 65
  • 78
  • Hi Benny, thank you for your answer! You are totally right about the way I had been setting the state of the knobs array. I've used your example to improve my code;) However, the problem of it not working only in Production mode remains. Everything works as expected in Development, it's super weird. – tracey Jun 18 '18 at 19:49
0

Oh, so in the end I rewrote the whole bit.

Moving the objects to be created into the render function.

export default class App extends React.Component {
  constructor() {
    super();
    this.state = {
      things: []
    }
    this.key = 0;
  }

  add = () => {
    let addThing = { key: this.key }
    this.setState({ things: [ ...this.state.things, addThing ] })
    this.key = this.key + 1;
  }

  render() {
    let newThings = this.state.things.map((key) => {
      return (
        <Text key={key}>New Thing.</Text>
      );
    });
    return (<View style={styles.container}>
      {newThings}
      <Button onPress={() => this.add()} title='add thing'/>
    </View>);
  }
}

This functions as expected in Production mode and as an App;)

tracey
  • 111
  • 1
  • 4