0

In my App.js, I have initialized some states like so,

export default class App extends React.Component {
  constructor(){
    super();
     this.state = {
            myfirststate: '',
            mysecondstate: '',
     }    
    }
    ...
   }

Now I have a ChildComponent.js which is stateless and is like this which has a button and when clicked, changes the state of myfirststate from null to hello.

 export default class ChildComponent extends React.Component {
   render() {
    return (
      <View>
        <Button
          title="clickme"
          onPress={() => 
             this.setState({myfirststate: "hello"})
        />
      </View>
      );
     }
    }

Is it possible to do something like this? I always thought I had to pass the value of states as arguements in a function which was passed from parent component to child like this instead.

App.js

 export default class App extends React.Component {
  constructor(){
   super();
    this.state = {
        myfirststate: '',
        mysecondstate: '',
     }    
   }

 functiontopassvalues(values) {
    this.setState({
        myfirststate: values
    })
   }
   <ChildComponent functiontopassvalues={this.functiontopassvalues} />
  }

And in ChildComponent.js I would do something like this

    export default class ChildComponent extends React.Component {
      render() {
        return (
         <View>
           <Button
            title="clickme"
             onPress={() => 
             {this.props.functiontopassvalues("hello")}
        />
      </View>
      );
     }
    }

I hope I am making sense, please let me know what is the correct method to do it and why it is so. Also, does it apply to both react native and react.js?

craftdeer
  • 985
  • 5
  • 20
  • 36
  • 3
    Passing a function as prop is the official pattern, as outlined here: https://stackoverflow.com/questions/35537229/how-to-update-parents-state-in-react In theory you can pass a reference to the parent to the child component, then use `parent.setState()` inside the child class. –  Mar 13 '18 at 07:42
  • 1
    Also, given that the answer to the title is a resounding "yes, of course", you might want to replace "change" with "reference". –  Mar 13 '18 at 07:53
  • @ChrisG, I am curious as to how one would reference the parent in the child component like you said. Do you have any links, and also would you be able to provide an example with my code? – craftdeer Mar 13 '18 at 08:00
  • 1
    I don't have links, and in practice it seems not really possible. I tried to write example code and the issue is that you can't pass the parent to the child as prop because the child is part of the parent's definition. Just use the official way: pass a function. –  Mar 13 '18 at 08:08
  • Understood. thank you – craftdeer Mar 13 '18 at 08:11

2 Answers2

1

Your way of solving the problem is a fair and correct, but it isn't necessarily scalable, and you are correct in that you can't alter state of a parent in a child.

I would recommend checking out tools like Redux, MobX or Apollo Link State that all try to solve the eternal problem of state management.

Sam Pettersson
  • 3,049
  • 6
  • 23
  • 37
  • OP shows *two* ways of solving the problem and is asking about his alternative as compared to the official way. Your answer is ambiguous, and one can of course very much alter a parent's state in a child. –  Mar 13 '18 at 07:51
1

Your approach is correct, but your child component is aware what value needs to be passed to parent, technically it is correct, but it's not scalable. You can pass an onPress handle to child component and in parent set whatever value you want in parent state.

Consider following example

export default class App extends React.Component {
 constructor(){
  super();
  this.state = {
    myfirststate: '',
    mysecondstate: '',
  }    
 }

 functiontopassvalues= (values) => {
  this.setState({
    myfirststate: values
  });
 }
 <ChildComponent title="click me" onPress={() => this.functiontopassvalues('hello')} />
}

Child component can be made scalable by a few changes

export default class ChildComponent extends React.Component {
  render() {
    return (
     <View>
       <Button
         title={this.props.title}
         onPress={this.props.onPress}
       />
     </View>
   );
 }
}

It is always better to use any state management tools as specified by @Sam. They are pretty helpful.

Prasun
  • 4,943
  • 2
  • 21
  • 23