Debug School

rakesh kumar
rakesh kumar

Posted on

Different way to reuse component in react native mobile app

In React Native (and React in general), mixins are not commonly used due to their limitations and conflicts in larger applications. Instead, modern React development focuses on using other approaches such as higher-order components (HOCs), render props, and hooks to share logic across components in a cleaner and more maintainable way.

Here's a breakdown of the main alternatives to mixins in React Native:

  1. Higher-Order Components (HOCs) A Higher-Order Component (HOC) is a function that takes a component and returns a new component with additional props or functionality. It allows for code reuse and logic sharing across components, similar to mixins but with a clearer and more explicit structure.

Example:

import React from 'react';
import { Text, View } from 'react-native';

// A simple higher-order component (HOC)
const withUserData = (WrappedComponent) => {
  return class extends React.Component {
    state = {
      user: {
        name: 'John Doe',
        age: 30
      }
    };

    render() {
      return (
        <WrappedComponent
          user={this.state.user}
          {...this.props} // Pass down other props to the wrapped component
        />
      );
    }
  };
};

// A component that receives user data via HOC
class UserInfo extends React.Component {
  render() {
    const { user } = this.props;
    return (
      <View>
        <Text>Name: {user.name}</Text>
        <Text>Age: {user.age}</Text>
      </View>
    );
  }
}

// Enhance UserInfo component with the HOC
const EnhancedUserInfo = withUserData(UserInfo);

export default EnhancedUserInfo;
Enter fullscreen mode Exit fullscreen mode
  1. React Hooks React Hooks are a newer and more powerful feature introduced in React 16.8. They allow you to manage state and side effects in function components, providing a cleaner and more modern alternative to class-based components and mixins.

Example:
Using custom hooks to share logic across components:

import React, { useState, useEffect } from 'react';
import { Text, View } from 'react-native';

// Custom hook to fetch user data
const useUserData = () => {
  const [user, setUser] = useState(null);

  useEffect(() => {
    // Simulate fetching user data
    const fetchData = () => {
      setUser({
        name: 'John Doe',
        age: 30
      });
    };

    fetchData();
  }, []); // Empty dependency array to run only once

  return user;
};

// A component using the custom hook
const UserInfo = () => {
  const user = useUserData();

  if (!user) return <Text>Loading...</Text>;

  return (
    <View>
      <Text>Name: {user.name}</Text>
      <Text>Age: {user.age}</Text>
    </View>
  );
};

export default UserInfo;
Enter fullscreen mode Exit fullscreen mode
  1. Render Props Render props is another technique for sharing logic across components. With this pattern, you pass a function as a prop to a component, which allows you to share functionality between components while giving the receiving component control over how to render the content.

Example:

import React from 'react';
import { Text, View } from 'react-native';

// Component with a render prop
class UserInfoProvider extends React.Component {
  state = {
    user: {
      name: 'John Doe',
      age: 30
    }
  };

  render() {
    return this.props.render(this.state.user);
  }
}

// Component that uses the render prop
const UserInfo = () => {
  return (
    <UserInfoProvider
      render={(user) => (
        <View>
          <Text>Name: {user.name}</Text>
          <Text>Age: {user.age}</Text>
        </View>
      )}
    />
  );
};

export default UserInfo;
Enter fullscreen mode Exit fullscreen mode
  1. Component Composition Component Composition is a basic yet powerful pattern in React where components are composed together to share logic and behavior. This is a more declarative approach than mixins and is recommended for modern React development.
import React from 'react';
import { Text, View } from 'react-native';

// Higher-order functional component for injecting user data
const UserInfo = ({ user }) => (
  <View>
    <Text>Name: {user.name}</Text>
    <Text>Age: {user.age}</Text>
  </View>
);

// Parent component
const App = () => {
  const user = { name: 'John Doe', age: 30 };

  return (
    <View>
      <UserInfo user={user} />
    </View>
  );
};

export default App;
Enter fullscreen mode Exit fullscreen mode
  1. Context API React Context API allows you to share values between components without having to explicitly pass props through every level of the tree. It is an ideal solution for global states (e.g., authentication status, theme settings, etc.).

Example:

import React, { useState, createContext, useContext } from 'react';
import { Text, View, Button } from 'react-native';

// Create a context
const UserContext = createContext();

// Component that provides user data
const UserProvider = ({ children }) => {
  const [user, setUser] = useState({ name: 'John Doe', age: 30 });

  return (
    <UserContext.Provider value={user}>
      {children}
    </UserContext.Provider>
  );
};

// Component that consumes user data from the context
const UserInfo = () => {
  const user = useContext(UserContext);

  return (
    <View>
      <Text>Name: {user.name}</Text>
      <Text>Age: {user.age}</Text>
    </View>
  );
};

// Main App component
const App = () => {
  return (
    <UserProvider>
      <UserInfo />
    </UserProvider>
  );
};

export default App;
Enter fullscreen mode Exit fullscreen mode

React Context AP

I
The Context API is a built-in feature in React that allows you to share data (such as state) across different components without needing to pass props manually through every component level.

How It Works:
Create Context: You create a context object using React.createContext().

Provider: The Provider component is used to make the context value available to any component in the component tree.

Consumer: You can consume the context value in any child component using the useContext hook or the Context.Consumer component.

Example of React Context API
Let’s go through a simple example to understand how the Context API works in React, similar to how Provider and Consumer work in Flutter.

  1. Create a Context: You create a context object using React.createContext().

import React, { createContext, useState } from 'react';

// Create a Context for managing state
const MyContext = createContext();

const MyProvider = ({ children }) => {
  // This is the state we want to share across components
  const [value, setValue] = useState('Hello, React!');

  return (
    // Provider is used to pass the state to all components inside it
    <MyContext.Provider value={{ value, setValue }}>
      {children}
    </MyContext.Provider>
  );
};
Enter fullscreen mode Exit fullscreen mode
  1. Wrap Your App with the Provider: You wrap your app or component tree with the MyProvider component so that the context value is available to all components inside it.
import React from 'react';
import { MyProvider } from './MyProvider'; // Import the Provider

import MyComponent from './MyComponent'; // Import a component where you will consume the context

const App = () => {
  return (
    <MyProvider>
      <MyComponent />
    </MyProvider>
  );
};

export default App;
Enter fullscreen mode Exit fullscreen mode
  1. Consume the Context in a Component: Now, inside any component, you can access the context value using useContext() or by using Context.Consumer.
import React, { useContext } from 'react';
import { MyContext } from './MyProvider';

const MyComponent = () => {
  // Consume the context value using the useContext hook
  const { value, setValue } = useContext(MyContext);

  return (
    <div>
      <h1>{value}</h1>
      <button onClick={() => setValue('Updated Value!')}>Update Value</button>
    </div>
  );
};

export default MyComponent;
Enter fullscreen mode Exit fullscreen mode

In the above example:

The MyProvider component provides a context (MyContext) with a value and setValue function.

The MyComponent consumes the context using the useContext hook to access and modify the value.

  1. Using Context.Consumer (Optional Alternative to useContext): Instead of using the useContext hook, you can use the Context.Consumer component. This is more verbose but works in class components or if you prefer not to use hooks.

import React from 'react';
import { MyContext } from './MyProvider';

const MyComponent = () => {
  return (
    <MyContext.Consumer>
      {({ value, setValue }) => (
        <div>
          <h1>{value}</h1>
          <button onClick={() => setValue('Updated Value!')}>Update Value</button>
        </div>
      )}
    </MyContext.Consumer>
  );
};

export default MyComponent;
Enter fullscreen mode Exit fullscreen mode

Comparison Between Flutter and React Concepts:
Flutter Provider:

In Flutter, Provider is a package that helps manage and inject state across the widget tree.

Consumer is used to access the provided state in child widgets.

React Context API:

React's Provider is used to share a value across components.

useContext (or Context.Consumer) is used to consume the shared value in any child component.

When to Use React Context API:
Global State Management: When you need to share data (like user authentication, theme preferences, language settings, etc.) across many components.

Avoid Prop Drilling: If you're passing props down many levels, context can help avoid "prop drilling" and make state management cleaner.

Top comments (0)