реагировать на странные ошибки типа данных контекста

#javascript #reactjs #react-context #react-dnd

Вопрос:

Я пытался узнать о контексте react и о том, как изменить его из дочернего компонента, но я продолжаю получать странные ошибки

здесь я создаю контекст массива и пытаюсь изменить его при отбрасывании элемента из дочернего элемента, но это приводит к ошибке TypeError: context.push не является функцией

 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; 

Комментарии:

1. Можете ли вы добавить трассировку ошибки стека в свой вопрос?

2. context это переменная только для чтения, если вы попытаетесь ее изменить, это не сработает, попробуйте [...context, item] вместо context.push(item)

Ответ №1:

В вашем коде есть три проблемы:

  1. Мутирующие состояния непосредственно с помощью Array.push
  2. ContextType s разные. Одно есть MyContext , другое есть WebsiteContext .
  3. Недопустимое значение по умолчанию предоставляется для createContext

Измените код следующим образом:

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);