javascriptreactjstypescriptreact-nativehigh-order-component

How to use HoC with React Native


I have an listing app where users can add items for multiple categories, when they want to add new record, there are 3 related screens with this particular feature. All of those screens have <Header/> component, so i thought HoC would be nice here so that i can reuse it across 3 screens. However, i could not accomplish it.

Here is what i tried so far:

This is my HoC class

import React, { Component } from 'react';
import { View, StyleSheet, Text, StatusBar } from 'react-native';
import Header from '../components/Header';

const NewAd = (WrappedComponent) => {
    class NewAdHoc extends Component {
        handleBackPress = () => {
            this.props.navigation.navigate('Home');
            StatusBar.setBarStyle('dark-content', true);
        }
        render() {
            const {contentText, children} = this.props
            return (
                <View style={styles.container}>
                    <Header
                        headerText={'Yeni ilan ekle'}
                        onPress={this.handleBackPress}
                    />
                    <View style={styles.contentContainer}>
                        <Text style={styles.contentHeader}>{contentText}</Text>
                        <WrappedComponent/>
                    </View>
                </View>
            );
        }
    }


    return NewAdHoc;
}

this is my screen:

class NewAdScreen extends Component {
    render() {
        const Content = () => {
            return (
                <View style={styles.flatListContainer}>
                    <ListViewItem />
                </View>
            );
        }
        return (
            NewAdHoc(Content)
        )
    }
}

after that i am getting error

TypeError: (0 , _NewAdHoc.NewAdHoc) is not a function(…)

and i have no idea how can i fix it because this is my first time using hocs on a react-native app. I have looked why this error is popping and they suggest import components in this way:

import {NewAdHoc} from '../hocs/NewAdHoc';

but even this is not solved it.

any help will be appreciated, thanks.


Solution

  • The main purpose of a HOC is to encapsulate and reuse stateful logic across components. Since you are just reusing some jsx and injecting nothing in WrappedComponent you should be using a regular component here:

    const NewAd = ({ contentText, children }) => {
    
        handleBackPress = () => {
            this.props.navigation.navigate('Home');
            StatusBar.setBarStyle('dark-content', true);
        }
    
    
        return (
            <View style={styles.container}>
                <Header
                    headerText={'Yeni ilan ekle'}
                    onPress={this.handleBackPress}
                />
                <View style={styles.contentContainer}>
                    <Text style={styles.contentHeader}>{contentText}</Text>
                    {children}
                </View>
            </View>
        );
    }
    

    And use it like this

    return(
        <>
             <NewAd>
                <Screen1 />
             </NewAd>
             <NewAd>
                <Screen2 />
             </NewAd>
             <NewAd>
                <Screen3 />
             </NewAd>
        </>
    )