【问题标题】:How to useState hooks with array如何使用带有数组的状态挂钩
【发布时间】:2021-10-22 21:11:36
【问题描述】:

我无法在 useState 数组中推送数字索引。 我哪里出错了,当我点击它们时,我想推送数字索引吗? 我正在提取以前的状态数组,然后我推送新的但没有任何反应。 如何在 useState 数组 React 钩子中推送新元素?我的代码不起作用!! 请有人检查。

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

随机数.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,
  },
});

【问题讨论】:

    标签: javascript reactjs react-native


    【解决方案1】:

    你没有调用函数

    onClick={() => selectNumber(index)}
    

    【讨论】:

    • 如果我按照你的说法我得到一个错误:错误:超过最大更新深度。当组件在 componentWillUpdate 或 componentDidUpdate 中重复调用 setState 时,可能会发生这种情况。 React 限制了嵌套更新的数量以防止无限循环。
    • 可能因为需要写&lt;TouchableOpacity onPress={handlePress}&gt;
    • 对我有用,但我不知道你想做什么。它只添加随机数并选择每个索引一次jsfiddle.net/t0po14wj/16,但这正是您编写代码的目的。当您在每次重新渲染时生成新数字时。
    • 如果我将其更改为 {handlePress}>然后我的号码将被选中,但每次点击时号码都会改变
    • 是的,兄弟,如果您选择了一个数字,请检查一次,然后它将被选中,但每个数字都在变化
    【解决方案2】:

    您需要更改 onClick 属性并将 randomNumber(或索引取决于您想要做什么)传递给 selectNumber 函数:

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

    【讨论】:

    • 错误:超过最大更新深度。当组件在 componentWillUpdate 或 componentDidUpdate 中重复调用 setState 时,可能会发生这种情况。 React 限制了嵌套更新的数量以防止无限循环。
    【解决方案3】:
    <TouchableOpacity onPress={handlePress()}>
    

    应该是

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

    () => selectNumber
    

    应该是

    () => selectNumber()
    

    请尝试一下

    【讨论】:

    • 这是有效的,但是当我点击它被选中的任何数字时,但每个数字都在一次又一次地改变
    • 所以把 ()=>handlePress() 改成 handlePress
    • 那么同样的问题
    • 怎么样:改变 ()=>handlePress() 到 handlePress 和 () => selectNumber() 到 selectNumber
    • 发生这种情况是因为您在每次重新渲染时重新生成了数字。但这正是您的代码应该做的。否则你必须改变世代。
    【解决方案4】:

    可能会有帮助:

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

    输出日志:

    【讨论】:

      猜你喜欢
      • 2020-05-31
      • 2021-10-23
      • 2020-05-19
      • 1970-01-01
      • 2021-05-19
      • 2019-10-20
      • 1970-01-01
      • 2020-02-20
      • 1970-01-01
      相关资源
      最近更新 更多