I am storing some data in my parent component to an array of objects. After that I am storing it in Context in order to pass it to another component. So my parent looks like this:
export type HistoryData = {
input: string;
date: string;
};
type Props = {
children?: ReactNode;
};
type ContextProviderType = {
history: HistoryData[];
setHistory: React.Dispatch<React.SetStateAction<HistoryData[]>>;
};
const values = {} as HistoryData;
export const Context = createContext<ContextProviderType>({
history: [],
setHistory: () => {},
});
export const Overview = ({ children }: Props) => {
const [inputText, setInputText] = useState('');
const [data, setData] = useState<any[]>([]);
const [loading, setLoading] = useState(false);
const [history, setHistory] = useState<HistoryData[]>([]);
const handleSubmit = (e: React.MouseEvent<HTMLElement>) => {
e.preventDefault();
setLoading(false);
axios
.get(`https://api.github.com/users/${inputText}/repos`)
.then((response) => {
setData(response.data);
})
.catch((error) => {
console.log('error', error);
setLoading(true);
});
const clonedValues = { ...values };
clonedValues.input = inputText;
clonedValues.date = new Date().toLocaleString();
setHistory([...history, clonedValues]);
};
console.log(history);
<Context.Provider value={{ history, setHistory }}>
....
</Context.Provider>
);
};
export const useContextData = () => useContext(Context);
So basically, after each input i am storing the input and the exact date of the input while it clicked, and later i want to pass it to the other component like that:
import { useContextData } from './Overview';
const History = () => {
const { history, setHistory } = useContextData();
console.log(history);
but all I get is an empty history
array [].
Just to clarify, the History
component is another page with /history
url...
I am not sure maybe that re-renders and clears the array??
My App.tsx:
function App() {
return (
<>
<Routes>
<Route path="/" element={<Overview />} />
<Route path="/history" element={<History />} />
</Routes>
</>
);
}
export default App;
And my index.tsx:
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
);
root.render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>
);
Any help would be appreciated! :)
In order to share a context, two components must be descendents of the same Provider. That means that you need to have the context provider as a parent to your components.
Export Context
and useContextData
into another file.
In your App.tsx
file you will need to wrap the routes in the context provider:
function App() {
const [history, setHistory] = useState<HistoryData[]>([]);
return (
<Context.Provider value={{ history, setHistory }}>
<Routes>
<Route path="/" element={<Overview />} />
<Route path="/history" element={<History />} />
</Routes>
</Context.Provider>
);
}
Then in each of the files you would access the history
and setHistory
props using context:
const History = () => {
const { history, setHistory } = useContextData();
export const Overview = ({ children }: Props) => {
const { history, setHistory } = useContextData();
This should solve the issue.