Home > Mobile >  onClick button not running function
onClick button not running function

Time:09-11

I'm new to Nextjs and I'm currently creating my first application. I have the following issue:

I created a function called build() that does the following:

  • Add 5 of the same element ("QuestionMark) to an array.
  • Clone "agents" array.
  • Run a for loop for the amount of "value" and pick a random agent then add it to the "picked" array and remove it from the clone array.
  • Return the picked array.

I then do

picked = build()

to update the picked array. Further in my code I do a map of "picked" array to display those images.

Here's the code in a formatted way for ease of understanding:


function formTeam() {
  let agents = [
    "Astra",
    "Breach",
    "Brimstone",
    "Chamber",
    "Cypher",
    "Jett",
    "KayO",
    "Killjoy",
    "Neon",
    "Omen",
    "Phoenix",
    "Raze",
    "Reyna",
    "Sage",
    "Skye",
    "Sova",
    "Fade",
    "Viper",
    "Yoru",
  ];
  const [value, setValue] = React.useState(0);
  const handleChange = (value) => setValue(value)

    let picked = Array(5).fill("QuestionMark");
    const build = () => {
        let clone = [...agents];
        for (let i = 0; i < value; i  ) {
            let random = Math.floor(Math.random() * clone.length);
            picked[i] = `${clone[random]}`;
            clone.splice(random, 1);
        }

        return picked;
    };
    picked = build();
  return (
    <div>
// This is where I get "value" (range 2-5)
      <FormControl>
        <Center>
          <FormLabel>Players</FormLabel>
          <NumberInput
            max={5}
            min={2}
            value={value}
            onChange={handleChange}
            w={"500px"}
          >
            <NumberInputField />
            <NumberInputStepper>
              <NumberIncrementStepper />
              <NumberDecrementStepper />
            </NumberInputStepper>
          </NumberInput>
        </Center>
      </FormControl>

      <Center>
        <Button
            onClick={build}
            >
            Build
            </Button>
      </Center>
      
      <Grid templateColumns={"repeat(5, 1fr)"} gap={20} mt={20}>
        {
// Mapping the array and making it return "AgentCard" which is basically just a box with the agent image on it, the passed in "image" is just the path to that image.
            picked.map(agent => {
                return (
                    <GridItem w="150px">
                        <AgentCard image={`/images/valorant/agents/${agent}.png`} />
                    </GridItem>
                )
            })
        }
      </Grid>
    </div>
  );
}

So what's happening here is that when the value changes, the grid is automatically updated which is amazing but when clicking "build" it doesn't really build (I will later rename "build" to "refresh") all I want it to do is upon clicking "build" it builds a different team formation (reruns build() and/or sets "picked" array to a new team combination.

I've tried so many different things now and I'm sure why this is happening tbh, please explain why this is happening and if there are any code optimisations or different methods you'd go around this.

P.S: I know the title might be a bit misleading to the situation but I honestly have no clue what else to put in there because I don't get what's not working or how to explain it in the title. If later on I find a better title or once it's solved I'll figure out a way to fix that.

Thank you in advance.

CodePudding user response:

All i want upon clicking "build" it builds a different team formation

So basically you want to update picked array on every click and re render the newly picked team.

To this you need to perform following

Your build function should not modify any variable of component,Instead it should return new object with modified data,Like this

const build = () => {
    let res= Array(5).fill("QuestionMark");
    let clone = [...agents];
    for (let i = 0; i < value; i  ) {
        let random = Math.floor(Math.random() * clone.length);
        res[i] = `${clone[random]}`;
        clone.splice(random, 1);
    }
    return res;
};

Now declare picked as a state of your component like this

const [picked,setPicked]=useState([])

Now to initialize picked ,You can directly call build with useState or You can use useEffect hook like this

useEffect(()=>{
   setPicked(build());
},[])`

Finally ,You should handle click event like this

<Button            onClick={()=>{ setPicked(build())    }}            >
  • Related