0

I have been trying to implement a context API solution since I want to use children states (data) in my app.js without lifting up the states. Anyways I have tried to implement it a context API solution by doing the following :

  1. I created a folder names context and then created Context.js. This is the code:

    import { createContext,useState } from "react";
    export const Mycontext = createContext()
    
    const Context = ({children}) =>{
        const [post, setPost] = useState([])
        return(
            <Mycontext.Provider value={[post,setPost]}>
                {children}
            </Mycontext.Provider>
        )
    }
    export default Context
    
  2. I wrapped the index.js file with the provider wrapper as follows:

    import ReactDOM from 'react-dom/client';
    import './index.css';
    import App from './App';
    import Context from './context/Context';
    
    const root = ReactDOM.createRoot(document.getElementById('root'));
    root.render(
      <Context>
         <App />
      </Context>
    );
    
  3. My main goal for now is to use useState hook data or states so I can use them in higher up components, in this case I want my post.js file to change usestate data in context so i can then use that data to post something in App.js using a container component that takes value as a props

I will post the both post.js and container.js and app.js below

import React,{useContext,useState,useEffect,useRef} from 'react'
import '../HomeMainStyling/HomeStyling.css'
import Tweets from './Tweets'
import Context from '../../context/Context'

function Tweet() {

    const tw = useRef('')
    
    const {post,setPost} = useContext(Context);
    useEffect(() => {
        if (post.length) console.log(post);
      }, [post]);
    
    function PostNow(event){
        
        event.preventDefault();
        
        setPost((oldpost) => [tw.current.value,...oldpost]);
        
        
        
        
    }
    
  return (
    
    <div className="tweetcontainer">
        <textarea ref={tw} className="tweetinfo"></textarea>
        <button className="postIt" onClick={PostNow}>tweet</button>
    </div>
    
  )
}

export default Tweet
//

the container is the following:

import React from 'react'
import '../HomeMainStyling/HomeStyling.css'
function Tweets({value}) {
  return (
    <h2>{value}</h2>
  )
}

export default Tweets

App.js:

import Tweet from './Center/HomeMain/Tweet';
import Tweets from './Center/HomeMain/Tweets';
import { useContext,useState } from 'react';
import Context from './context/Context';
function App() {
  const {post,setPost} = useContext(Context);
  return (
    <div className="App">
      
      <Tweet/>
      <Tweets value={post}/>
    </div>
  );
}

export default App;

The app should in principle post 1 h1 element for every click in Tweet components

1
  • Your using an array for value [post,setPost] and then detructuring it like an object. {post,setPost}, did you mean const [post, setPost] = useContext(Context); Alternatively set value as an object -> value={{post,setPost}} Commented Nov 10, 2022 at 10:25

2 Answers 2

2

The useContext hook takes the context you created using createContext() as a parameter, but you are passing a custom component to it, so try:

import { Mycontext } from './context/Context';

const [post, setPost] = useContext(Mycontext)
Sign up to request clarification or add additional context in comments.

4 Comments

Oh, yeah that too. This question is a good example of where Typescript would shine, the destructuring incorrectly and not using the actual context would have been flagged instantly.
hey there is still get an error even after doing that
the error says:Invalid hook call. Hooks can only be called inside of the body of a function component but the thing is i never used a hook outside the main function body
@Techlover69 Unfortunately I cannot tell from the code you posted why that error is being thrown. Here is a minimal example using your code codesandbox.io/s/focused-brahmagupta-qpqjt2 which throws no errors.
0

<Mycontext.Provider value={[post,setPost]}>

this is wrong you ahve to write

<Mycontext.Provider value={{post,setPost}}>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.