Search code examples
reactjsreact-context

Function which sets context property value is empty but works. Why?


I'm making a very basic program using React Context following a tutorial on YouTube. One part really confused me though, there are two properties in the default context:

import React from "react"

const defaultContext = {
    markdownText: "",
    setMarkdownText: () => {},    
}

export default React.createContext(defaultContext)

The setMarkdownText property is never then actually updated and remains an empty function.

const {setMarkdownText} = useContext(editorContext)

const onInputChange = e => {
    const newValue = e.currentTarget.value;
    setMarkdownText(newValue)
}

Then how is setMarkdownText actually changing the markdownText property despite being an empty function in the code above?

A link to the complete project on codesandbox.io


Solution

  • Actual values are passed to context provider in App.js. Default context values are just safety mechanism in case someone will make consumer without provider.

    Here is relevant documentation: https://reactjs.org/docs/context.html

    Explanation:

    // editorContext.js
    
    // this is our default "fallback" values for context
    const defaultContext = {
      markdownText: "",
      setMarkdownText: () => {},
    };
    
    // We are creating context instance
    export default React.createContext(defaultContext);
    
    // App.js
    export default function App() {
      //  this state and state setting fucntion will be our actual context value
      const [markdownText, setMarkdownText] = useState("");
      // we prepare it here
      const contextValue = {
        markdownText,
        // This is our actual `setMarkdownText`
        setMarkdownText,
      };
    
      // and pass it into EditorContext.Provider as a value prop
      // This value will be used for every consumer inside the tree, instead of default value
      return (
        <EditorContext.Provider value={contextValue}>
          <AppContainer>
            <Title>Markdown Editor</Title>
            <EditorContainer>
              <MarkedInput />
              <Result />
            </EditorContainer>
          </AppContainer>
        </EditorContext.Provider>
      );
    }