Search code examples
javascriptreactjsnext.jsreact-propsuse-state

How to pass get parameter data to a component in react?


I am using react(next.js) to build a simple application. In this particular case, I'm trying to create a form in add and edit mode. If the get parameter contains edit, the form makes some api calls else it makes some different api calls. I'm passing the get paramaters as props but that doesn't seem to work.

Here's my code from the page:

  const [formMode, setFormMode] = useState(h.form.FORM_MODE.ADD);
  const [selectedContactId, setSelectedContactId] = useState("");

  useEffect(() => {
    const contact_id = h.findGetParameter("contact_id");
    setSelectedContactId(contact_id);
    const form_mode = h.findGetParameter("form_mode");
    setFormMode(form_mode);
    console.log(form_mode);
    console.log(contact_id);
  }, []);

  return (
    <div >
      <Header />
      <Body>
        <div className="container projects-container">
          <div className="mb-5 projects-title">
            <h1> Create Link</h1>
          </div>
          <CreateMyForm
            setLoading={setLoading}
            formMode={formMode}
            setFormMode={setFormMode}
            selectedContactId={selectedContactId}
          />
        </div>
      </Body>
      <Footer />
    </div>

I'm taking get parameters contact_id and form_mode from the URL, setting them into in useState(which is working fine and being printed in console), and then passing them to the CreateMyForm component as props. It doesn't seem to be received in the component. Below is part of my code from the component which requires these parameters.

  const { setLoading, formMode, setFormMode, selectedContactId } = props;

  useEffect(() => {
    // const contact_id = h.findGetParameter("contact_id");
    // console.log("contact id = ", contact_id);
    // setSelectedContactId(contact_id);
    // const form_mode = h.findGetParameter("form_mode");
    // setFormMode(form_mode);
    // // console.log(contact_id);
    // console.log("latest = ", form_mode);
    // console.log("latest = ", selectedContactId);

    (async () => {
      if (h.cmpStr(formMode, h.form.FORM_MODE.EDIT)) {
        const selectedContactRes = await api.contact.findById(
          { contact_id: selectedContactId },
          {},
          false
        );
        console.log("Her's me agains: ", selectedContactRes.data);
        setSelectedContact(selectedContactRes.data.contact);
      }

      let projectApiRes = await api.project.contentFindAll({}, {}, false);
      if (h.cmpStr(projectApiRes.status, "ok")) {
        if (
          projectApiRes.data.projects &&
          projectApiRes.data.projects.length > 0
        ) {
          let projects = handleProjectOptionList(projectApiRes.data.projects);
          setProjects(projectApiRes.data.projects);
          setProjectList(projects);
        }
      }

      if (h.cmpStr(formMode, h.form.FORM_MODE.ADD)) {
        let contactApiRes = await api.contact.findAll({}, {}, false);
        if (h.cmpStr(contactApiRes.status, "ok")) {
          if (
            contactApiRes.data.contacts &&
            contactApiRes.data.contacts.length > 0
          ) {
            let contacts = handleContactOptionList(contactApiRes.data.contacts);
            console.log("I am coming here");
            setContactList(contacts);
          }
        }
      }
    })();

  }, []);

I've even tried to try to capture the get parameters in the component but that doesn't seem to work either. I'm guessing the problem is with the async API calls but I am not sure how to fix it. Any help please. Thanks in advance


Solution

    1. Your useEffect() function is running only when the component loads.
    2. You have to call all the code inside of useEffect everytime contact_id or form_mode changes so I suggest you pass these as observable arguments to useEffect as follows
    useEffect(()=>{
       // All your runnable code
    
    }, [contact_id, form_mode])
    
    1. Now all your code inside will run each time contact_id or form_mode is even slightly changed

    2. Also, I would recommend you to wrap all your awaits in a try-catch block so you can test out how well the API works