Yes, there are several ways to avoid prop drilling and make state accessible across components without integrating everything into a single component. Here are the main approaches:
1. React Context API (Most Common Solution)
This is the built-in React solution for sharing state across components without prop drilling:
Step 1: Create a context and provider
jsx// StateContext.js
import { createContext, useContext, useState } from 'react';
const StateContext = createContext();
export const StateProvider = ({ children }) => {
const [state, setState] = useState({
// your initial state here
user: null,
theme: 'light',
// etc.
});
return (
<StateContext.Provider value={{ state, setState }}>
{children}
</StateContext.Provider>
);
};
export const useAppState = () => {
const context = useContext(StateContext);
if (!context) {
throw new Error('useAppState must be used within StateProvider');
}
return context;
};
Step 2: Wrap your app with the provider
jsx// App.js
import { StateProvider } from './StateContext';
function App() {
return (
);
}
Step 3: Use the state in any child component
jsx// AnyChildComponent.js
import { useAppState } from './StateContext';
function AnyChildComponent() {
const { state, setState } = useAppState();
const updateUser = (newUser) => {
setState(prev => ({ ...prev, user: newUser }));
};
return (
<div>
<p>Current user: {state.user?.name}</p>
<button onClick={() => updateUser({ name: 'John' })}>
Set User
</button>
</div>
);
}