0

My target is to transfer a state boolean value to parent component, which can use for hiding and showing another child components. Example: I have three components. ListViewComponent, ErrorMessageComponent and ParentComponent(which binds first two). In ListViewComponent there is a boolean which is true only if backend data length is zero. I want to send that boolean in parent component and show or hide ErrorMessageComponent according to that boolean.

ListViewComponent:

validateData(newProps){
    this.props.onDataLengthZero(newProps.data.length == 0);
}

ParentComponent:

render() {
    return (
        <View>
            <ListViewComponent />
            <ErrorMessageComponent errorText="My error message Text" />
        </View>
    );
}

How can I consume onDataLengthZero in parent component and hide ErrorMessageComponent if it is true?

IntoTheDeep
  • 4,027
  • 15
  • 39
  • 84
  • how about passing a callback function down from parent to child? https://facebook.github.io/react/tips/communicate-between-components.html – azium Sep 18 '16 at 22:28

2 Answers2

5

Instead of trying to pass a boolean back up your hierarchy, pass the data down. Get the backend data in ParentComponent so you can check its length there, and then pass the data down to the ListViewComponent.

If you absolutely have to do it back up the other way you can pass a callback function down from ParentComponent to ListViewComponent but that is conceptually harder to follow.

david
  • 17,925
  • 4
  • 43
  • 57
  • If I have 100 components with backend data should I pass it to parent? I did not accept that as answer. My question is strict – IntoTheDeep Sep 18 '16 at 22:32
  • 1
    If you have 100 components with backend data then you should probably build them out as a service rather than mixing them with your rendering logic. If you re-read my answer I do mention how you can pass data back up, but you need to understand that you lose a large part of the benefit of unidirectional data flow that react encourages. – david Sep 18 '16 at 22:36
  • This is same to tell me to show error in child. This is not an answer. Getting backend data in parent is out of the question. – IntoTheDeep Sep 18 '16 at 22:38
  • 1
    It's very different to telling you to show the error in the child. In fact it does a better job of removing error logic from the child. In your scenario the `ListViewComponent` is responsible for notifying the `ErrorMessageComponent` (via the parent) that an error has occurred. If instead you make the parent component the owner of the data then the `ListViewComponent` will only be responsible for displaying the data. Nothing else. – david Sep 18 '16 at 22:51
  • ListviewComponent is responsible to show backend data and checks about it. ParentComponent is responsible just to binds all components. No logic or back end data. – IntoTheDeep Sep 18 '16 at 22:55
  • 1
    Yes, that's how you are thinking about it. But I'm telling you that it is not the best way to think about it, and that is why you are having to ask this question. – david Sep 18 '16 at 22:56
  • So proper is to post all 1000 Components data in single component and to add 1000 methods for check up those backend datas? – IntoTheDeep Sep 18 '16 at 22:58
  • 1
    Actually that is what a lot of data frameworks recommend. A single place to store application state makes it much easier to reason about the flow of information. You are of course making a false equivalence here because you don't have 1000 components, you just have 3. And we're talking about moving one instance of data ownership up just a single tier. – david Sep 18 '16 at 23:01
  • Ok, I can think about it. But which is more easy: to transfer a single boolean or transfer let say 1000 records data through components? Or now you will say to me that my data is not 1000 records – IntoTheDeep Sep 18 '16 at 23:11
  • 1
    You're only passing down a reference to the data, you're not actually copying all 1000 records. And you're right in that you don't want to pass data down too far. You need to make a judgement call, if you're passing data down too many layers then you should probably move that data out into a service of some kind. – david Sep 18 '16 at 23:18
  • How to do that? I want to pass data only once. What is the remedy – IntoTheDeep Sep 18 '16 at 23:19
  • 1
    You either do it yourself or you pick a framework to do it for you. Many people use redux for their data management, but there are others. You'd have to decide which one best suits your needs. – david Sep 18 '16 at 23:25
  • I use redux. My data comes from redux-saga – IntoTheDeep Sep 18 '16 at 23:26
0

You can comunicate with the parent component by sending a prop to the child with a callback function. You could set the parent's state there (with the boolean). Then you can invoke that function in your child component and modify the state of the parent. You can find an example of this mechanism here. In your case, it would be something like:

Parent Component:

showError(){
    this.setState({
        showError: true;
    });

}
render() {
    let error = undefined;
    if(this.state.showError == true){
        error = <ErrorMessageComponent errorText="My error message Text" />;
    }
    return (
        <View>
            <ListViewComponent handleError={this.showError}/>
            {error}
        </View>
    );
}
Community
  • 1
  • 1
César Landesa
  • 2,626
  • 1
  • 13
  • 18