简体   繁体   中英

React native: rendering conditional component based on state value change in Modal

I have a requirement of showing a tab like behavior inside a react native Modal

I have started by creating a state variable selectedSub which is initialized with value 'from'

Now my modal has 2 TouchableHighlight as below

_availabiltyModal() {
return (
<TouchableHighlight
    onPress={() => { this.setState({ selectedSub: 'from' }) }}
    activeOpacity={0.9}
    style={[styles.tab, this.state.selectedSub == 'from' && styles.active]}>
        <RkText rkType="header" style={this.state.selectedSub == 'from' && styles.activeText}>From</RkText>
</TouchableHighlight>
<TouchableHighlight
    onPress={() => { this.setState({ selectedSub: 'to' }) }}
    activeOpacity={0.9}
    style={[styles.tab, this.state.selectedSub == 'to' && styles.active]}>
        <RkText rkType="header" style={this.state.selectedSub == 'to' && styles.activeText}>To</RkText>
</TouchableHighlight>
{this._renderPicker()}
)}

These two are responsible to change the state param selectedSub as required.

Based on this state param i am conditionally showing another component i made and imported as below

_renderPicker() {
    if (this.state.selectedSub == 'from') {
        return <TimePicker screenProps={{ time: this.state.selectedAvailabilty.from }} />
    } else {
        return <TimePicker screenProps={{ time: this.state.selectedAvailabilty.to }} />
    }
}

I have called this function in the Modal below the TouchableHighlight's

Now as per the RN docs when ever the state variable is updated with this.setState() method the component should re-render. Everything else is working fine ( TouchableHighlight styles changing ) and also the updates to the state are reflecting in the console. But the _renderPicker function does not return the changed view and is always stuck on the view which was set when the parent was initialized as pointed earlier.

Could somebody help me point the problem here which i might have been overlooking. Also on the side note all this calls are actually directly made outside the main render() method. Could that be a possible issue

------update------ here is the complete reference

 render() {
    return({this._availabiltyModal()}
    <View style={appStyles.tagsWrapper}>
        {this.state.week.map((day, i) => {
            return (
                <TouchableHighlight
                    key={i}
                    activeOpacity={0.9}
                    style={[appStyle.mr10, appStyle.mb10]}
                    onPress={() => {
                       this.setModalVisible(true, day);
                    }}>
                    <Text style={appStyle.tag}>{day}</Text>
                </TouchableHighlight>
            )
        })}
     </View>
    )
}

Move the _renderPicker method inside the render() method like...

render() {
...
{this._renderPicker()}
...
} 

Looking at the code of the MODAL component from react-native

render(): React.Node {
    ....
    const innerChildren = __DEV__ ? (
      <AppContainer rootTag={this.context.rootTag}>
        {this.props.children}
      </AppContainer>
    ) : (
      this.props.children
    );

    return (
      <RCTModalHostView
        ....>
        <View style={[styles.container, containerStyles]}>
           {innerChildren} 
        </View>
      </RCTModalHostView>
    );
  }

The state you are changing are of the component that use the modal component thats render its children through the upper function.. when the state update it only re render the component whose state is updated.. so somewhere down rendering child inside component it does not get re render until force re render is applied.

Here is an helpful article to further explain how exactly this functions, forcefully re-rendering the child component

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM