1

I am not able to push the number index in the array of useState. Where I am going wrong, do I want to push the index of numbers when I click them? I am extracting the previous state array and then I push new but nothing happens. How to push a new element inside useState array React hook? My code doesn't work!! Please someone check.

Game.js

import { StatusBar } from "expo-status-bar";
import React, { useState } from "react";
import { StyleSheet, Text, View } from "react-native";
import RandomNumber from "./RandomNumber";

export default function Game(props) {
  const [state, setstate] = useState([]);
  let randomNumber = Array.from({ length: props.randomNumberCount }).map(
    () => 1 + Math.floor(10 * Math.random())
  );
  let target = randomNumber
    .slice(0, props.randomNumberCount - 2)
    .reduce((acc, curr) => acc + curr, 0);
  const isNumberSelected = (numberIndex) => {
    return state.indexOf(numberIndex) >= 0;
  };
  const selectNumber = (numberIndex) => {
    setstate((arr) => [...arr, numberIndex]);
  };
  return (
    <View style={styles.container}>
      <Text style={styles.header}>Target Sum Game</Text>
      <Text style={styles.target}>{target}</Text>
      <View style={styles.randomContainer}>
        {randomNumber.map((randomNumber, index) => (
          <RandomNumber
            key={index}
            id={index}
            number={randomNumber}
            isSelected={isNumberSelected(index)}
            onClick={() => selectNumber}
          />
        ))}
      </View>
      <StatusBar style="auto" />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#ddd",
    paddingTop: 30,
  },
  target: {
    fontSize: 30,
    backgroundColor: "#aaa",
    margin: 50,
    marginHorizontal: 70,
    textAlign: "center",
  },
  header: {
    fontSize: 35,
    backgroundColor: "dodgerblue",
    textAlign: "center",
    marginHorizontal: 30,
    marginTop: 50,
  },
  randomContainer: {
    flexDirection: "row",
    flexWrap: "wrap",
    justifyContent: "space-around",
  },
});

RandomNumber.js

import React from "react";
import { StyleSheet, Text, TouchableOpacity } from "react-native";

export default function RandomNumber(props) {
  const handlePress = () => {
    props.onClick(props.id);
  };
  return (
    <TouchableOpacity onPress={handlePress()}>
      <Text style={[styles.random, props.isSelected && styles.selected]}>
        {props.number}
      </Text>
    </TouchableOpacity>
  );
}

const styles = StyleSheet.create({
  random: {
    backgroundColor: "#999",
    width: 100,
    marginHorizontal: 35,
    marginVertical: 25,
    fontSize: 35,
    textAlign: "center",
  },
  selected: {
    opacity: 0.3,
  },
});

4 Answers 4

1

you are not calling the function

onClick={() => selectNumber(index)}
Sign up to request clarification or add additional context in comments.

11 Comments

if i this according to you i get an error:Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.
maybe because you need to write <TouchableOpacity onPress={handlePress}>
workes for me, but i don't know what you want do. it only adds random numbers and selects each index once jsfiddle.net/t0po14wj/16 but that is exactly what your code is written for. as you generate new numbers on each rerender.
if i change this to <TouchableOpacity onPress=()=>{handlePress}>then my number will be selected but number is changing everytime I click
yeah bro you check once if you select a number then it will be selected but every number is changing
|
0

You need to change the onClick prop and pass the randomNumber (or index depending of what you want to do) to the selectNumber function:

// Not sure if you want to pass randonNumber or index but you get the idea
onClick={() => selectNumber(randomNumber)}

1 Comment

Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.
0
<TouchableOpacity onPress={handlePress()}>

should be

<TouchableOpacity onPress={()=>handlePress()}>

and

() => selectNumber

should be

() => selectNumber()

please try it

6 Comments

This is working but when i click on any number it got selected but but every number is changing then again and again
so change ()=>handlePress() to handlePress
then same problem
how about : change ()=>handlePress() to handlePress and () => selectNumber() to selectNumber
it happens because you regenerate the numbers on each rerender. but that is exactly what your code should do. otherwise you have to change the generation.
|
0

Might Be This Helpful:

Home.Js

import React, {useState, useEffect} from 'react';
import {StyleSheet, Text, View, TouchableOpacity} from 'react-native';
import RandomNumber from './RandomNumber';

const Home = props => {
  const [state, setstate] = useState([]);

  useEffect(() => {
    console.log('state', state);
  }, [state]);

  let randomNumber = Array.from({length: 10}).map(
    () => 1 + Math.floor(10 * Math.random()),
  );

  let target = randomNumber
    .slice(0, props.randomNumberCount - 2)
    .reduce((acc, curr) => acc + curr, 0);

  const isNumberSelected = numberIndex => {
    return state.indexOf(numberIndex) >= 0;
  };

  const selectNumber = numberIndex => {
    console.log('numberIndex', numberIndex);
    setstate(arr => [...arr, numberIndex]);
  };

  return (
    <View style={styles.container}>
      <Text style={styles.header}>Target Sum Game</Text>
      <Text style={styles.target}>{target}</Text>
      <View style={styles.randomContainer}>
        {randomNumber.map((randomNumber, index) => {
          return (
            <RandomNumber
              key={index}
              id={index}
              number={randomNumber}
              isSelected={isNumberSelected(index)}
              onClick={() => selectNumber(randomNumber)}
            />
          );
        })}
      </View>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#ddd',
    paddingTop: 30,
  },
  target: {
    fontSize: 30,
    backgroundColor: '#aaa',
    margin: 50,
    marginHorizontal: 70,
    textAlign: 'center',
  },
  header: {
    fontSize: 35,
    backgroundColor: 'dodgerblue',
    textAlign: 'center',
    marginHorizontal: 30,
    marginTop: 50,
  },
  randomContainer: {},
});

export default Home;

RandomNumber.js

import React from 'react';
import {StyleSheet, Text, View, TouchableOpacity} from 'react-native';

export default function RandomNumber(props) {
  const handlePress = () => {
    props.onClick(props.id);
  };
  return (
    <View style={{}}>
      <TouchableOpacity onPress={() => handlePress()}>
        <Text style={[styles.random, props.isSelected && styles.selected]}>
          {props.number}
        </Text>
      </TouchableOpacity>
    </View>
  );
}

const styles = StyleSheet.create({
  random: {
    backgroundColor: '#999',
    width: 100,
    height: 100,
    marginHorizontal: 35,
    marginVertical: 25,
    fontSize: 35,
    textAlign: 'center',
  },
  selected: {
    opacity: 0.3,
  },
});

Output Log:

output

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.