How to Pass Data Between Reactjs Components?

Passing data between React components is a fundamental part of building React applications. Here are several common methods to achieve this:

1. Props

Props are the primary way to pass data from a parent component to a child component.

// ParentComponent.js
import React from 'react';
import ChildComponent from './ChildComponent';

const ParentComponent = () => {
  const data = "Hello from Parent!";
  return <ChildComponent message={data} />;
};

export default ParentComponent;

// ChildComponent.js
import React from 'react';

const ChildComponent = ({ message }) => {
  return <div>{message}</div>;
};

export default ChildComponent;

2. State Lifting

When two sibling components need to share data, you can lift the state up to their common ancestor and pass it down as props.

// ParentComponent.js
import React, { useState } from 'react';
import Sibling1 from './Sibling1';
import Sibling2 from './Sibling2';

const ParentComponent = () => {
  const [sharedData, setSharedData] = useState("Shared Data");

  return (
    <div>
      <Sibling1 data={sharedData} />
      <Sibling2 setData={setSharedData} />
    </div>
  );
};

export default ParentComponent;

// Sibling1.js
import React from 'react';

const Sibling1 = ({ data }) => {
  return <div>{data}</div>;
};

export default Sibling1;

// Sibling2.js
import React from 'react';

const Sibling2 = ({ setData }) => {
  return <button onClick={() => setData("New Data")}>Update Data</button>;
};

export default Sibling2;

3. Context API

The Context API allows you to share data globally across your component tree without having to pass props down manually at every level.

// MyContext.js
import React, { createContext, useState } from 'react';

export const MyContext = createContext();

export const MyProvider = ({ children }) => {
  const [data, setData] = useState("Context Data");

  return (
    <MyContext.Provider value={{ data, setData }}>
      {children}
    </MyContext.Provider>
  );
};

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

const ParentComponent = () => {
  return (
    <MyProvider>
      <ChildComponent />
    </MyProvider>
  );
};

export default ParentComponent;

// ChildComponent.js
import React, { useContext } from 'react';
import { MyContext } from './MyContext';

const ChildComponent = () => {
  const { data, setData } = useContext(MyContext);

  return (
    <div>
      <p>{data}</p>
      <button onClick={() => setData("Updated Context Data")}>Update Data</button>
    </div>
  );
};

export default ChildComponent;

4. Custom Hooks

Custom hooks can encapsulate shared logic and data and be used across different components.

// useSharedData.js
import { useState } from 'react';

const useSharedData = () => {
  const [data, setData] = useState("Shared Data via Hook");

  return { data, setData };
};

export default useSharedData;

// ParentComponent.js
import React from 'react';
import useSharedData from './useSharedData';
import ChildComponent from './ChildComponent';

const ParentComponent = () => {
  const sharedData = useSharedData();

  return <ChildComponent sharedData={sharedData} />;
};

export default ParentComponent;

// ChildComponent.js
import React from 'react';

const ChildComponent = ({ sharedData }) => {
  const { data, setData } = sharedData;

  return (
    <div>
      <p>{data}</p>
      <button onClick={() => setData("Updated Data via Hook")}>Update Data</button>
    </div>
  );
};

export default ChildComponent;

5. Third-Party State Management Libraries

Libraries like Redux or MobX provide robust solutions for managing global state across an application.

Redux Example

// store.js
import { createStore } from 'redux';

const initialState = { data: "Redux Data" };

const reducer = (state = initialState, action) => {
  switch (action.type) {
    case 'UPDATE_DATA':
      return { ...state, data: action.payload };
    default:
      return state;
  }
};

export const store = createStore(reducer);

// ParentComponent.js
import React from 'react';
import { Provider } from 'react-redux';
import { store } from './store';
import ChildComponent from './ChildComponent';

const ParentComponent = () => {
  return (
    <Provider store={store}>
      <ChildComponent />
    </Provider>
  );
};

export default ParentComponent;

// ChildComponent.js
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';

const ChildComponent = () => {
  const data = useSelector((state) => state.data);
  const dispatch = useDispatch();

  return (
    <div>
      <p>{data}</p>
      <button onClick={() => dispatch({ type: 'UPDATE_DATA', payload: "Updated Redux Data" })}>Update Data</button>
    </div>
  );
};

export default ChildComponent;

These methods provide flexibility in how you manage and share data across your React components, depending on the complexity and requirements of your application.

Up Next
    Ebook Download
    View all
    Learn
    View all