2

I have been trying to learn about the react context and how to change it from the child component but i keep getting weird errors

here i make an array context and try to change it on item drop from child but it gives me error TypeError: context.push is not a function

import { React, createContext, useContext } from "react";
import { useState } from "react";

import { useDrag, useDrop } from "react-dnd";
import { DndProvider } from "react-dnd";
import { HTML5Backend } from "react-dnd-html5-backend";

function WebsiteBody(props) {
  const [context, add_to_context] = useContext(WebsiteContext);

  const [{ droppedItem, didDrop, isOver, canDrop }, drop] = useDrop(() => ({
    accept: "card",
    drop: () => ({
      name: "body",
    }),
    collect: (monitor) => ({
      droppedItem: monitor.getItem(),
      didDrop: monitor.didDrop(),
      isOver: monitor.isOver(),
      canDrop: monitor.canDrop(),
    }),
  }));
 
  if (didDrop) {
    add_to_context(droppedItem.item);
  }

  return (
    <div
      ref={drop}
      w="100vw"
      h="100vh"
      backgroundColor="yellow"
      display="flex"
    >
      
      {dropped_items.map((item) => item.name)}
    </Box>
  );
}

const MyContext = createContext([]);

function App(props) {
  const [context, setContext] = useState([]);

  function add_item(item) {
    setContext(context.push(item));

  }

  return (
      <DndProvider backend={HTML5Backend}>
        <MyContext.Provider value={[context, add_item]}>
          <WebsiteBody></WebsiteBody>
        </MyContext.Provider>
      </DndProvider>
  );
}

export default App;
Omar Alhussani
  • 162
  • 1
  • 12

1 Answers1

2

There are three problems in your code:

  1. Mutating states directly using Array.push
  2. ContextTypes are different. One is MyContext, the other is WebsiteContext.
  3. Invalid default value is provided for createContext

Modify the code like the following:

WebsiteContext.js

export default React.createContext([
  [],  // default value for context value 
  () => {} // default value for addItem
]);

App.js

import WebsiteContext from './WebsiteContext';

const [context, setContext] = useContext([]);

const addItem = (item) => {
  setContext(old => [...old, item]);
};

<WebsiteContext.Provider value={[context, addItem]}>
</WebsiteContext.Provider>

WebsiteBody.js

import WebsiteContext from './WebsiteContext';

const [context, add_to_context] = useContext(WebsiteContext);
glinda93
  • 7,659
  • 5
  • 40
  • 78