1

I am trying to update the state in a method start() and then passing the state's value to MyComponent. My component works ok, and the state updates ok when I'm setting it within the class, but when I'm trying to pass it from start method - it doesn't work. getting "TypeError: this.setState is not a function"

Edited - fixed binding but something still doesn't work.

What can be the problem?

export default class App extends Component{
  constructor (props){
    super(props);
    this.state = {
      val: false
    }
    this.start= this.start.bind(this)

  }

  start() {
    this.setState({ val: true })
  }

  render(){
    return (
      <View>
        <Button 
        title='start' 
        onPress={this.start}>
        </Button>

        <MyComponent value={this.state.val}> </MyComponent>
      </View>
    );
  }
}

this is MyComponent:

class MyComponent extends Component {
     constructor(props){
         super(props)
         this.state={}
         this.state.custum={
            backgroundColor: 'red'
         }
         let intervalid;
         if (this.props.value){
            setTimeout(() => {
                this.setState( {
                    custum:{
                        backgroundColor: 'green'
                    }
                    })
            }, 1000);
            setTimeout(() => {
                this.setState( {
                    custum:{
                        backgroundColor: 'red'
                    }
                    })
            }, 2000);
        }
     }    
    render() {
        return (
            <View style={[styles.old, this.state.custum]}> 
            </View>
        );
      }
    }  
    var styles = StyleSheet.create({
        old:{
          padding: 5,
          height: 80,
          width: 80,  
          borderRadius:160,    

        },
    })
export default MyComponent;
Shiranox
  • 101
  • 1
  • 9
  • It sounds like you're having an issue when calling `start` as an event handler (ie. when you click the button). The problem is related to the context in which the method is called - basically, when `start` is called via an event handler, `this` does not refer to the component. See [this answer](https://stackoverflow.com/a/20279485/2008384) for a detailed discussion – Kryten Jan 17 '20 at 18:56
  • The problem is event handler binding; many, many dupes. – Dave Newton Jan 17 '20 at 18:57

4 Answers4

1

You have to bind the context to your function.

 constructor (props){
      super(props);
        this.state = {
        val: false
    }
    this.start = this.start.bind(this)
  }

or just you can an arrow function, without binding

 start = () => {
     this.setState({ val: true })
 }
Roman Unt
  • 893
  • 7
  • 8
0

You have to bind the method with this. Just add

this.start = this.start.bind(this)

after this.state in the constructor.

EDIT

And also try to move custom inside state in MyComponent like this:

this.state={
  custum: {
    backgroundColor: 'red'
  }
}

and remove

this.state.custum={
 backgroundColor: 'red'
}

As you can't just set state like this.

Nipun Jain
  • 999
  • 6
  • 13
0

bind start method to the component other 'this' will be undefined for the start function

export default class App extends Component{
  constructor (props){
    super(props);
    this.state = {
      val: false
    }
    this.start = this.start.bind(this)
  }

  start() {
    this.setState({ val: true })
  }

  render(){
    return (
      <View>
        <Button 
        title='start' 
        onPress={this.start}>
        </Button>

        <MyComponent value={this.state.val}> </MyComponent>
      </View>
    );
  }
}
Aldrin
  • 2,036
  • 15
  • 12
0

You need to make start function to be binded through constructor or ES6 arrow function.

export default class App extends Component{
  constructor (props){
    super(props);
    this.state = {
      val: false
    }
  }

  start = () => {
    this.setState({ val: true })
  }

  render(){
    return (
      <View>
        <Button 
        title='start' 
        onPress={this.start}>
        </Button>

        <MyComponent value={this.state.val}> </MyComponent>
      </View>
    );
  }
}
Rise
  • 1,493
  • 9
  • 17