skip to Main Content

The file Editor.js in the components directory contains this

const Editor = () => {
  //some states
  const [mathEditorVisible, setMathEditorVisible] = useState(false);
  //some other code
}

This is Form.js in the utils directory:

  //some imports
    export const handleSaveFormula = (latex) => {
     //some code
     setMathEditorVisible(false);   
    };

This is Editor.js in the utils directory:

//some exports
export const editExpression = () => {
//some code
 setMathEditorVisible(true);
 };

Now, I want to import the setMathEditorVisible from Editor.js in the components directory where it is defined to the Editor.js and Form.js files in the utils directory.
This error occurs if I do not import it
**ERROR in [eslint] src/utils/Editor.js
Line 17:8: ‘setMathEditorVisible’ is not defined no-undef

src/utils/Form.js
Line 49:7: ‘setMathEditorVisible’ is not defined no-undef
**
And of course it will because it is undefined for now.

2

Answers


  1. u can move the state to component alone and import it

    export default function State() {
      const [mathEditorVisible, setMathEditorVisible] = useState(false);
      return {mathEditorVisible,setMathEditorVisible}
    }
    

    now u can impoet it in any component

    import State from "State.jsx"
    export const editExpression = () => {
      const {mathEditorVisible,setMathEditorVisible}=State()
    //u can use the state objects now
     };
    
    Login or Signup to reply.
  2. You’ll have to manage this without imports. Since the state setter is just a local variable in a component function.

    However, fear not, this problem can be solved in a couple other ways:

    Parameters

    You can pass mathEditorVisible and setMathEditorVisible into Editor and into your handleSaveFormula and editExpression functions from component of a higher level (e.g. page).

    It will look something like this:

    // page.tsx
    const Page = () => {
      ...
      const [mathEditorVisible, setMathEditorVisible] = useState(false)
      ...
      return <>
       ...
       <Editor visible={mathEditorVisible} /> 
       ...
       <button onClick={() => {
         setMathEditorVisible(false)
         handleSaveFormula()
       }}>Your submit flow</button>
       <button onClick={() => {
         setMathEditorVisible(true)
         editExpression()
       }}>Your edit flow</button>
      </>
    }
    
    

    Context

    Another way to do this is put your variables into context (which would have to be on top of Editor component and the functions you’re calling setMathEditorVisible in).

    Context lets you access its values in any (even nested) child components.

    So, in this situation you would store your [mathEditorVisible, setMathEditorVisible] in value property of a context component (ContextObject.Provider) created by React.createContext. Then later you can access the values through useContext hook, passing the original context object as the argument.

    Here’s the example:

    // mathEditor.tsx
    const EditorContext = React.createContext<[boolean, (v: boolean) => void]>([false, () => {}])
    
    const Editor = () => {
      const [mathEditorVisible] = useContext(EditorContext)
      ...
    }
    
    
    // page.tsx
    
    const SubmitFlow = () => {
      ...
      const [,setMathEditorVisible] = useContext(EditorContext)
      return <>
        ...
        <button onClick={() => setMathEditorVisible(false)}>Submit</button>
      </>
    }
    const EditFlow = () => {
      ...
      const [,setMathEditorVisible] = useContext(EditorContext)
      return <>
        ...
        <button onClick={() => setMathEditorVisible(true)}>Edit</button>
      </>
    }
    
    const Page = () => {
      const [mathEditorVisible, setMathEditorVisible] = useState(false)
      return <>
        ...
        <EditorContext.Provider value={[mathEditorVisible, setMathEditorVisible]}>
          <Editor />
          <SubmitFlow />
          <EditFlow />
        </EditorContext.Provider>
      </>
    }
    
    

    Note that with context, since you have to call useContext hook, you would need to retrieve values in a component, and if needed, pass it to underlying functions.

    Conclusion

    As some other people already mentioned, you’re probably better off with the first approach. However, it’s good to know how context works, in case you need to access something in a lot unconnected components/places.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search