Problem while passing data from child to parent

I’ve read that you can’t really pass props upwards like that, but you can do so through functions. I went and found a workaround and it worked.

My problem is: I’m trying to get data to App from 2 layers down - App > DataInput > ValidateUser - so I can pass it over from App to 2 other components.

I can get the data from ValidateUser back to DataInput, just before sending it to App I’m logging the result and it’s all as expected. The problem begins when I try to send it to App and the data I receive is undefined.

I checked a few times to see if I was making a typo or logical error while implementing the second data call. Unless I completely missed it, nothing. I started to think that, maybe, then, the problems might be with the execution order. App is read first so, maybe, it wasn’t getting updated once I assigned the value further down the execution line? But then, I’m updating the state when I click the button and it prints out the undefined and the blank object again being called from App while I can see the object is fully filled when it’s last called over the handler in DataInput…

I’m probably missing something here.

App

import "./App.css";
import Box from "@mui/material/Box";
import React from "react";
import DataInput from "./components/DataInput";
import UserDataTable from "./components/UserDataTable";

const App = () => {
  let userData;
  let formSubmited = false;

  const getUserData = (params) => {
      console.log(params);
      userData = { ...userData, ...params };
      console.log(userData);
  };

  return (
    <div className="App">
      <Box
        sx={{
          width: 1000,
          height: 600,
          backgroundColor: "rgba(197, 202, 255, 1)",
          m: 4,
          border: 1.4,
          borderColor: "rgba(140, 150, 255, 1)",
        }}
      >
        <DataInput sendData={getUserData} />

        <UserDataTable />

        <div className="Author">
          <h3>André Lourenço</h3>
        </div>
      </Box>
    </div>
  );
};

export default App;

DataInput

import {
  TextField,
  Select,
  MenuItem,
  FormControl,
  InputLabel,
} from "@mui/material";
import { LoadingButton } from "@mui/lab";
import React, { useRef, useState } from "react";
import SaveIcon from "@mui/icons-material/Save";
import "../styles/DataInput.css";
import ValidateUser from "./ValidateUser";

export default function DataInput(props) {
  //State & Ref Hooks
  const [country, setCountry] = useState("");

  const handleCountryChange = (event) => setCountry(event.target.value);

  const countryInputRef = useRef();
  const nameInputRef = useRef();
  const surnameInputRef = useRef();
  const birthdayInputRef = useRef();

  const [rawData, setRawData] = useState("");

  // I/O
  let returnUserData;

  const handleFormSubmission = (event) => {
    event.preventDefault();

    let data = {
      name: "",
      surname: "",
      country: "",
      birthday: "",
    };

    data.name = nameInputRef.current.value;
    data.surname = surnameInputRef.current.value;
    data.country = countryInputRef.current.value;
    data.birthday = birthdayInputRef.current.value;

    setRawData(data);
  };

  const getValidatedData = (params) => {
    returnUserData = { ...returnUserData, ...params };
    returnUserData.isSubmited = true;
    console.log(returnUserData);
  };

  const handleSendData = (data) => props.sendData(data);

  return (
    <div className="DataInput">
      <form>
        <div className="Input-Boxes">
          <div className="Box-Name">
            <TextField
              sx={{ input: { color: "blue" } }}
              label="Name"
              inputRef={nameInputRef}
              required
            />
          </div>

          <div className="Box-Surname">
            <TextField
              sx={{ input: { color: "blue" } }}
              label="Surname"
              inputRef={surnameInputRef}
              required
            />
          </div>

          <div className="Box-Country">
            <FormControl variant="filled" sx={{ minWidth: 220 }}>
              <InputLabel id="demo-simple-select-filled-label">
                Countries
              </InputLabel>

              <Select
                required
                labelId="demo-simple-select-filled-label"
                id="demo-simple-select-filled"
                label="Countries"
                value={country}
                autoWidth
                onChange={handleCountryChange}
                inputRef={countryInputRef}
              >
                <MenuItem value={"Brazil"}> Brazil </MenuItem>
                <MenuItem value={"Portugal"}> Portugal </MenuItem>
              </Select>
            </FormControl>
          </div>

          <div className="Box-Birthday">
            <TextField
              sx={{ input: { color: "blue" } }}
              label="Birthday"
              inputRef={birthdayInputRef}
              type="date"
              InputLabelProps={{ shrink: true }}
              required
            />
          </div>
        </div>

        <div className="Button-Save">
          <LoadingButton
            loadingPosition="end"
            endIcon={<SaveIcon />}
            variant="outlined"
            type="submit"
            onClick={handleFormSubmission}
          >
            Save
          </LoadingButton>
          <ValidateUser data={rawData} sendData={getValidatedData} />
        </div>
      </form>

      {handleSendData(returnUserData)}
    </div>
  );
}

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.