React isn't updating a variable from a function

Viewed 68

I'm using axios to return a map to my main app where it will be distributed to other values in the program. I am having an issue though. When I use 'onClick' on a drop down select, I want it to call that external function to return the JSON string and save it to a variable but it won't do it. I have console logged it and it says my variable is use undefined. Here is my axios code

    import axios from "axios";

// ** when you launch server. Make sure 'express stuff' server is working and that it is posting to 5000/loadCycle
function Parent() {
  let data = null;
  console.log("called");
  const url = "http://localhost:5000/";

  axios
    .get(`${url}loadCycle`)
    .then((response) => {
      data = response.data.workflow;
      data = JSON.stringify(data);
      data = JSON.parse(data);
      //console.log(data);

  

const map = new Map(Object.entries(data));
  console.log(map);

  return map;
})
.catch((error) => console.error(`Error: ${error}`));
}

export default Parent;

and here is the code I want to format

    function App() {
      let dataCollection = null;

  return (
    <div>
      <Box
        sx={{ display: "flex", width: "40%", justifyContent: "space-between" }}
      >
        <Box sx={{ display: "flex" }}>
          {/* <Typography sx={{ paddingTop: "6%" }}>Cycle</Typography> */}

          {/* Cycle dropdown menu */}

          {/* // MAKE CHANGES ON BRANCH // */}
          <FormControl
            sx={{ m: 1, minWidth: 200 }}
            size="small"
            variant="standard"
          >
            <InputLabel>Cycles</InputLabel>
            <Select>
              <MenuItem value="">
                <em>None</em>
              </MenuItem>
              <MenuItem value={10} onClick={dataCollection=Parent()}>Ten</MenuItem>
              <MenuItem value={20}>Twenty</MenuItem>
              <MenuItem value={30}>Thirty</MenuItem>
            </Select>
          </FormControl>
          {/* cycle dropdown menu end */}
        </Box>
    </div>
    )

Why won't selecting 'one' from my select update dataCollection from 'null' to the map I am trying to return to it. Console logging it shows that the 'map' data in Parent is correct but the log for dataCollection is 'undefined'

2 Answers
<MenuItem value={10} onClick={dataCollection=Parent()}>Ten</MenuItem>

First of all you didn't define function (you are tried to do it like in a vainilla js, but react don't work in this way) So, let's define separate function:

const handleSave = () => {
  dataCollection=Parent()
}
// ...
<MenuItem value={10} onClick={handleSave}>Ten</MenuItem>

Next problem that's what your Parent function isn't synchronous, you should return your axios promise and after that use this function like that:

Parent().then(data => {
  dataCollection = data;
})

That's not all, we can't save data at dataCollection, because your functional component this is like render function and you will lose your data on next render, so you shoud save your data to ref or state (depending on the purpose of use), let's use state:

const [dataCollection, setDataCollection] = React.useState();
// ...
const handleSave = () => {
  Parent().then(data => {
    setDataCollection(data);
  })
}

Besides this I can see some style issues. And looks like you haven't read react doc attentively, please read againg "state and props" and "lifecycle" subjects from docs.

You have a couple of issues with your approach. I'm not sure what the other components: Box, FormControl, InputLabel, Select, and MenuItem are doing, so it makes it harder to discern if they are functioning correctly. I would simplify the code and just use regular HTML select and option tags. The select tag receives a change event and with React all events can be prefixed with "on", so it would be onChange on the select tag.

Create a prototype, a simpler project, that just focuses on that functionality until you understand it for your needs. Also, practice naming constructs a bit better, as Parent doesn't convey what it is doing. Aim to be succinct and general.

Related