Home > Software engineering >  React - State not updating through context
React - State not updating through context

Time:04-21

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. enter image description here

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.

  • Related