Search code examples
javascriptreactjsreact-hooksuse-statereact-props

Problem while passing useState variable from one JSX file to another


(CreateColumn.jsx)

import React, { useState, useEffect } from "react";
import Axios from "axios";
import "./styles.css";
function CreateColumn() {

  let [val1, setVal1] = useState("0");
  let [val2, setVal2] = useState("0");
  let [secName, setSecName] = useState("");
  let [goAttendance, setGoAttendance] = useState(0);

  function valueChanged(event) {
    const checkChecked = event.target.id;
    // console.log(checkChecked);
    if (checkChecked === "section1") {
      setVal1("1");
      setVal2("0");
      setSecName("Section 1");
    } else if (checkChecked === "section2") {
      setVal2("1");
      setVal1("0");
      setSecName("Section 2");
    } else {
      setVal1("0");
      setVal2("0");
      setSecName("");
    }
  }
    useEffect(() => {
      Axios.get("http://localhost:9000/createColumn").then((response) => {
        setSecName(response.data);
      });
    }, []);

  function sendColumn(event) {
    setGoAttendance(1);
    Axios.post("http://localhost:9000/createColumn", { secName, goAttendance });
  }

  return (
    <div>
      <form className="form-body">
        <div className="form-check check-line center-col">
          <input
            className="form-check-input"
            type="checkbox"
            id="section1"
            name="section"
            value={val1}
            checked={val1 === "1"}
            onChange={valueChanged}
          />
        </div>

        <div className="form-check check-line center-col">
          <input
            className="form-check-input"
            type="checkbox"
            id="section2"
            name="section"
            value={val2}
            checked={val2 === "1"}
            onChange={valueChanged}
          />
        </div>
        <div className="submit-btn d-grid gap-2 d-md-flex justify-content-md-center">
          <button
            type="submit"
            className="btn btn-lg btn-primary"
            onClick={sendColumn}
          >
            Create
          </button>
        </div>
      </form>
    </div>
  );
}

export default CreateColumn;

(Attendance.jsx)

import React, { useState, useEffect } from "react";
import Axios from "axios";
import TableTitle from "./TableTitle";
import Pagination from "./Pagination";
import "./styles.css";

function Attendance() {
  const [attedanceList, setAttedanceList] = useState([]);

  useEffect(() => {
    Axios.get("http://localhost:9000/attendance/" + ****WANT TO USE secName FROM CreateColumn.jsx HERE****).then(
      (response) => {
        setAttedanceList(response.data.data.values);
      }
    );
  }, []);

  function sendAllValues(event) {
    Axios.post("http://localhost:9000/attendance", { attedanceList });

  }

  return (
    <form className="form-body">
      <TableTitle />
      <Pagination data={attedanceList} />
      <div className="submit-btn d-grid gap-2 d-md-flex justify-content-md-center">
        <button
          type="submit"
          className="btn btn-lg btn-primary"
          onClick={sendAllValues}
        >
          Submit
        </button>
      </div>
    </form>
  );
}

export default Attendance;

(App.jsx)

import React, { useState } from "react";
import Attendance from "./Attendance";
import CreateColumn from "./CreateColumn";

function App() {
  return (
    <div>
      <CreateColumn />
      **WANT TO USE goAttendance FROM CreateColumn.jsx HERE** && <Attendance />
    </div>
  );
}

export default App;

I wanna use useState variables (secName and goAttendance) from Column.jsx in Attendance.jsx and App.jsx (where I have marked as WANT TO USE...). How is it possible?

More precisely, I wanna use secName from Column.jsx into Attendance.jsx. Also, I wanna use goAttendance from Column.jsx into App.jsx

I tried so many things for hours but sometimes it breaks my code or simply have to change a lot which makes the code more messy and buggy.


Solution

  • As I can see CreateColumn and Attendence are the child components of App. You want to create a state and use it in app where as you want to set it in its child component. What I will suggest is to create the state and setState function on app level and then pass the state and setState function as props in the child component. I will suggest you to see this to know more about props.

    in app.jsx

    let [val1, setVal1] = useState("0");
    let [val2, setVal2] = useState("0");
    let [secName, setSecName] = useState("");
    let [goAttendance, setGoAttendance] = useState(0);
    const [attedanceList, setAttedanceList] = useState([]);
     
    // while calling the components 
    return(
    <>
    <CreateColumn val1={val1}, val2={val2}, secName={secName}, ....../>
    <Attendance val1={val1}, val2={val2}, secName={secName}, ....../>
    </>
    )
    

    in CreateColumn and Attendence while declaring the components write

    function Attendance({val1, val2, secName, setVal1, ...})
    

    and then use the states and setStates in app.jsx