Deepak Mane
Deepak Mane

Reputation: 25

How to pass data from one js file to another js file through app.js in reactjs?

I have a joinQuiz.js file where users can join a quiz. I want when the user hits the join button, the quiz title and quiz id data to be passed on the next page i.e quiz.js file via App.js file. I used react-router to navigate through the files

joinQuiz.js

<Table striped bordered hover>
    <thead>
        <tr>
            <th>
                Quiz
            </th>
            <th>
                 Join
            </th>
        </tr>
    </thead>
    <tbody>
        {info.map((quiz) => (
            <tr>
                <th>
                    <h5>{quiz.title}</h5>
                    <p> Creator : {quiz.creator}  {quiz.email}</p>
                </th>
                <th>
                    <Button type="submit" href="/quiz"> Join </Button> //(HERE I WANT TO PASS QUIZ DATA TO NEXT PAGE I.E QUIZ.JS)
                </th>
            </tr>
        ))}
    </tbody>
</Table>

App.js file. here I have used react-router to navigate to the files. I don't know if I can directly pass the data from joinQuiz.js to quiz.js without doing any changes in app.js.

function App() {
  return (
    <div>
      <Router>
        <Header />
        <Switch>
          <Route path="/" exact component={Home} />
          <Route path="/creategame" exact component={createGame} />
          <Route path="/join" exact component={JoinQuiz} />
          <Route path="/quiz"  exact component={Quiz} />
        </Switch>
        <Footer/>
      </Router> 
    </div>
  );
}

quiz.js

Here I want to catch the quiz data when the user hits the join button.

const Quiz = ( props) => {
    const [questions, setQuestions] = useState([]);
    const [id, setId] = useState('jAApdF8FrX9GSMnDziCxm');
    const [type, setType] = useState('mcq');
    const[name, setName] = useState('');
    const[email,setEmail] = useState('');
    const [step, setStep] = useState(0);
    const[score, setScore] = useState(0)
    var result = 0
    var response = []
    const array = []

    useEffect(() => {
        axios.post("http://localhost:3500/app/initialdata", { id: id })
            .then((response) => {
                setQuestions(response.data.message)
            })
    }, [])

    return ( 
        <Container style={{paddingTop:"80px"}}>      
            <h3 style={{paddingTop: "20px", marginLeft:"20px"}}>Quiz " **Here I want to print qui title ***  </h3>
            <p style={{marginLeft:"20px"}}>Type : **Here I want to print Quiz Type *** </p>
            <p style={{marginLeft:"20px"}}>Creator : </p>
        </Container>
    )
}

Upvotes: 0

Views: 835

Answers (1)

nihilok
nihilok

Reputation: 2043

I think you're asking about how to import.

Quick answer, in one file you must export the variable, and the in the other you must import it.

first.js

export const myConst = 'A string or whatever'

target.js

import {myConst} from './first.js'

console.log(myConst)
// 'A string or whatever'

See the link for more information.

EDIT

After trying to decipher your problem, I think you might need to use useContext and a dispatcher. Context is like state that is available to all components within the context provider.

Another way of doing this would be to have state (or a ref) at the App level and pass this as props (as you correctly said) to both the quiz component and the joinQuiz component. Then inside the joinQuiz.js component you set the state to the data you want, before linking to the quiz route, then the data will be available inside the quiz page.

App.js

function App() {
  const [quizState, setQuizState] = useState(null)
  return (
    <div>
      <Router>
        <Header />
        <Switch>
          <Route path="/" exact component={Home} />
          <Route path="/creategame" exact component={createGame} />
          <Route path="/join" exact component={() => <JoinQuiz setState={setQuizState}/>} />
          <Route path="/quiz"  exact component={() => <Quiz state={quizState} />} />
        </Switch>
        <Footer/>
      </Router> 
    </div>
  );
}

joinQuiz.js (minimal)

import React from 'react';
import {useHistory} from 'react-router-dom';

const JoinQuiz = ({setState}) => {     // setState passed from App.js
  
  let history = useHistory();

  const handleSubmit = (quizData) => (event) => {
    event.preventDefault();
    setState(quizData)             // this is where you set the state you want to use in the other component
    // then navigate to the next page:
    history.push('/quiz')
  }
    
  return (
      <Table>
        ...
        <Button onClick={handleSubmit(quizData)}> Join </Button>
        ...
      </Table>
  );
};

export default JoinQuiz;

Quiz.js

const Quiz = ({state}) => {      // this is the quizState that gets set when you click the button.

  ... // your other logic and state etc.

  return ( 
    <Container style={{paddingTop:"80px"}}>      

      ... // the rest of your component

    </Container>
  )
}

Incidentally, you will want to use <td></td> inside your table body for the cells, rather than <th></th> which is for header cells.

EDIT 2

Here's a really simple example:


const App = () => {

  const [quizState, setQuizState] = useState(null)

  return (
      <div>
        <Route path={'/choose'} component={() => <JoinQuiz setQuizState={setQuizState}/>}/>
        <Route path={'/quiz'} component={() => <Quiz quizState={quizState}/>}/>
      </div>
  );
};

const JoinQuiz = ({setQuizState}) => {
  let history = useHistory();

  const handleButtonClick = (event) => {
    event.preventDefault()
    setQuizState({question: "What's the answer?", answer: '42'})
    history.push('/quiz')
  }

  return (
      <button onClick={handleButtonClick}>Join</button>
  );
};
const Quiz = ({quizState}) => {
  return (
      <div>
        {quizState.question}
        <input type="text" />
      </div>
  );
};

Then after clicking the button you should see something like this:

enter image description here

I don't think I can break it down for you any more than this! :)

Upvotes: 1

Related Questions