I'm trying to show/hide a component on my page using a state in a context being changed by one of the components on the page. I have a file upload box on my page, and when a valid file is uploaded, I want to show an element on the page, however I can't seem to get it to work at all. Can anyone see what I'm doing wrong at all?
It looks like the dispatch is updating the state value (as seen below from browser debugger), however the state does not seem to be updating on the Dashboard.js page.
index.js
...
import Provider from './Helpers/Provider'
ReactDOM.render(
<BrowserRouter>
<Provider>
<App />
</Provider>
</BrowserRouter>,
document.getElementById('root')
);
Dashboard.js
import { useDropzone } from 'react-dropzone';
import TileGrid from '../Components/TileGrid';
import MyDropzone from '../Components/Dropzone';
import React, { useState, useEffect } from 'react';
import { Context } from '../Helpers/Provider';
export default function Dashboard() {
const [currentTime, setCurrentTime] = useState(0);
const [state, dispatch] = useState(Context);
....
return (
<div>
<h5 >Upload a PCAP file to analyse</h5>
<p>Accepted file types: .pcap, .pcapng, .tcpdump</p>
</div>
<div >
<MyDropzone/> // File upload component
</div>
<div>
<p>{state.pcapUploaded}</p> // Should show 'false' by default, does not show at all
{ state.pcapUploaded ? <TileGrid tiles={tiles}/> : null } // Trying to get this item to show if a file has been uploaded, and not if no file has been uploaded
</div>
);
}
Dropzone.js (Trying to change the state to 'true' here)
import { useCallback, useEffect, useContext } from 'react';
import { useDropzone } from 'react-dropzone';
import { Context } from '../Helpers/Provider';
export default function MyDropzone() {
const [state, dispatch] = useContext(Context);
function PcapUploaded() {
alert("hi");
dispatch({ // Trying to update the state in context to have a value of 'true' here
type: 'UPLOADED',
payload: true,
});
}
const onDrop = useCallback(acceptedFiles => {
// Do something with the files
// alert(acceptedFiles[0].name);
PcapUploaded();
}, [])
.....
Provider.js
import { createContext, useReducer } from "react";
import Reducer from "../Reducer";
export const Context = createContext();
const initalState = {
pcapUploaded: false,
}
export default function Provider(props) {
const [state, dispatch] = useReducer(Reducer, initalState);
return (
<Context.Provider value={[state, dispatch]}>
{props.children}
</Context.Provider>
);
}
Reducer.js
export default function Reducer(state, action) {
switch(action.type) {
case 'UPLOADED':
return {
pcapUploaded: true,
};
default:
throw new Error();
}
}
I've been following this guide: https://remarkablemark.org/blog/2021/03/21/managing-react-state-with-context/
Thanks
CodePudding user response:
In you're Dashboard.js
try
const [state, dispatch] = useContext(Context)
Instead of
const [state, dispatch] = useState(Context)
CodePudding user response:
https://codesandbox.io/s/state-not-updating-through-context-98zlz6
Please check my codesandbox with working version of your code. There had been made some mistakes in types in your code, also you are using useState where useContext should be used.