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>
);
}