1

I have one parent view's. And I imported a header into this view. In this header there are two buttons. And with these buttons I change the values in a state. Button name Login / Register. I want to listen to the state values of these buttons, from the parent. How can I do that?

Child

export default class LoginRegisterHeader extends Component {
constructor(props) {
    super(props);
    this.state = {
        loginButtonActive: true,
        registerButtonActive: false
    };
}
login = () => {
    this.setState({ loginButtonActive: true, registerButtonActive: false });
}
register = () => {
    this.setState({ loginButtonActive: false, registerButtonActive: true });
}
render() {
    return (
        <View style={styles.viewStyle}>
            <Image source={require(logoSource)} style={styles.logo} />
            <View style={styles.buttonContainer}>
                <TouchableOpacity style={this.state.loginButtonActive == true ? styles.buttonActive : styles.buttonPassive} onPress={this.login}>
                    <Text style={this.state.loginButtonActive == true ? styles.buttonActiveText : styles.buttonPassiveText}>Login</Text>
                </TouchableOpacity>
                <TouchableOpacity style={this.state.registerButtonActive == true ? styles.buttonActive : styles.buttonPassive} onPress={this.register}>
                    <Text style={this.state.registerButtonActive == true ? styles.buttonActiveText : styles.buttonPassiveText}>Register</Text>
                </TouchableOpacity>
            </View>
        </View>
    );
}}

Parent:

class Login extends React.Component{
render(){     
    return(
        <View>
            <LoginRegisterHeader />
            //according to the values I've read here, I will get the third and fourth components
        </View>
    )
}}export default Login;
Can Kurucu
  • 75
  • 2
  • 10
  • Possible duplicate of [React js change child component's state from parent component](https://stackoverflow.com/questions/39041710/react-js-change-child-components-state-from-parent-component) – KarlR Aug 28 '18 at 12:01

2 Answers2

0

I guess the best way to do this is to add onLogin and onRegister props in the child component and pass it as a function from your parent component.

class Login extends React.Component{

onLogin = (newLoginValue) => {
 //Do something
}

onRegister = (newRegisterValue) => {
 //Do something
}

render(){     
    return(
        <View>                   // HERE!
            <LoginRegisterHeader onLogin={this.onLogin} onRegister={this.onRegister}/>
            //according to the values I've read here, I will get the third and fourth components
        </View>
    )
}}export default Login;

And in the child component, you call this props when you change your state.

import PropTypes from 'prop-types';

static props = { // Make sure to declare them as well
  onLogin: PropTypes.func,
  onRegister: PropTypes.func
}

static defaultProps = { // Declare a default value for the function
                        // in case you forget to pass them as props your code 
                        // wont crash                             
  onLogin: () => console.log('Login'),
  onRegister: () => console.log('Register'),
}

export default class LoginRegisterHeader extends Component {
constructor(props) {
    super(props);
    this.state = {
        loginButtonActive: true,
        registerButtonActive: false
    };
}
login = () => {
    this.setState({ loginButtonActive: true, registerButtonActive: false });
    this.props.onLogin(valueYouWant) //HERE!
}
register = () => {
    this.setState({ loginButtonActive: false, registerButtonActive: true });
    this.props.onRegister(valueYouWant) //HERE!
}
render() {
    return (
        <View style={styles.viewStyle}>
            <Image source={require(logoSource)} style={styles.logo} />
            <View style={styles.buttonContainer}>
                <TouchableOpacity style={this.state.loginButtonActive == true ? styles.buttonActive : styles.buttonPassive} onPress={this.login}>
                    <Text style={this.state.loginButtonActive == true ? styles.buttonActiveText : styles.buttonPassiveText}>Login</Text>
                </TouchableOpacity>
                <TouchableOpacity style={this.state.registerButtonActive == true ? styles.buttonActive : styles.buttonPassive} onPress={this.register}>
                    <Text style={this.state.registerButtonActive == true ? styles.buttonActiveText : styles.buttonPassiveText}>Register</Text>
                </TouchableOpacity>
            </View>
        </View>
    );
}}
Lucas Fabre
  • 1,806
  • 2
  • 11
  • 25
0

React is alctually one way binding between components. It it recommended to structure your app in parent to child relations and if you want to trigger changes in parent component with child interactions here comes the props concept. The idea way to handle this situation to write logic in your parent component and pass handlers as props to your children components. You don't need to call constructor unless you need props in it.

class Login extends React.Component{
  state = {
    loginButtonActive: true,
    registerButtonActive: false
  };

login = () => {
    this.setState({ loginButtonActive: true, registerButtonActive: false });
}
register = () => {
    this.setState({ loginButtonActive: false, registerButtonActive: true });
}
render(){     
    return(
        <View>
            <LoginRegisterHeader login={this.login} register ={this.register />
            //according to the values I've read here, I will get the third and fourth components
        </View>
    )
}}export default Login;

Child component:

export default class LoginRegisterHeader extends Component {

render() {
return (
     <View style={styles.viewStyle}>
            <Image source={require(logoSource)} style={styles.logo} />
            <View style={styles.buttonContainer}>
                <TouchableOpacity style={this.state.loginButtonActive == true ? styles.buttonActive : styles.buttonPassive} onPress={this.props.login}>
                    <Text style={this.state.loginButtonActive == true ? styles.buttonActiveText : styles.buttonPassiveText}>Login</Text>
                </TouchableOpacity>
                <TouchableOpacity style={this.state.registerButtonActive == true ? styles.buttonActive : styles.buttonPassive} onPress={this.props.register}>
                    <Text style={this.state.registerButtonActive == true ? styles.buttonActiveText : styles.buttonPassiveText}>Register</Text>
                </TouchableOpacity>
            </View>
        </View>
    );
}}
Sakhi Mansoor
  • 7,832
  • 5
  • 22
  • 37