Search code examples
reactjsuse-contextreact-beautiful-dnd

How to prevent refresh of list over API after drag & drop with beautiful DND?


I simulated my Context + DND problem in https://codesandbox.io/s/adoring-booth-33vqo . I have other components which will be added to this example and I will use a Context hook to share values across the page.

After the initial render, everything looks fine. The idea of the list is to change the order within itself and when ones changes the order with drag-drop, it throws an "Invalid Hook" error.

So the (first) real question is, what is triggering this error which is linked to the line

const { lang1Library, updateLang1Library } = useContext(LangContext) ;

Thanks in advance for your help. Geo


Solution

  • It's not a good approach to provide a link for the whole project even if it is small. But I had a quick look and there's at least one thing you're doing wrong:

    // DragEndFct.js
    export default function DragEndFct(result, libName) {
      const { lang1Library, updateLang1Library } = useContext(LangContext);
    

    This is not React component, but it uses a hook - and it is wrong. Hooks have a special meaning in React and should be used properly (Rules of Hooks).

    You can't use hooks inside regular functions and expect them to work. That is why you are getting that error.

    So, there are many ways you can try to fix this. For instance, DragEndFct is a regular function, you can declare more arguments and pass stuff you get from context:

    // you are using it in components right ?
    function DragEndFct(result, libName, param3, param4) {}
    
    // so you probably have access to the context there
    // and can pass data from the context when you call it.
    // something like this
    onDragEnd={function (result) {
        console.log();
        DragEndFct(result, StaticVars.LANG1_LIBRARY_NAME, lang1Library, updateLang1Library);
    }}
    

    You could even make DragEndFct to be a React component - it can just return null (which means no UI will be rendered) but in that case you will have hooks and all other stuff there. It really depends on what you need and how you will use it.