React Native函数组件中如何防止按钮点击时页面刷新及随机数组重新初始化
解决React Native中点击按钮时随机数组重复初始化的问题
嘿,我明白你遇到的困扰了!每次点击按钮计数器递增,但随机数组也跟着重新生成,这是因为你把randomNoArry直接定义在组件的函数体里——组件每次重新渲染(比如count状态变化时),这段数组生成代码都会重新执行,自然就会得到新的随机数组。
下面给你两种简单有效的解决方案:
方案一:使用useState初始化数组(推荐用于需要后续修改数组的场景)
把随机数组的生成逻辑放到useState的初始值函数里,这样它只会在组件第一次挂载时执行一次,之后不会再重新生成:
import React, { useState } from "react"; import { Button, Text, View } from "react-native"; const Game1 = (props) => { const [count, setCount] = useState(0); // 用useState的初始函数生成数组,仅执行一次 const [randomNoArry] = useState(() => Array.from( { length: parseInt(props.randomnno) }, // 注意把字符串转成数字,否则length会出错 () => 1 + Math.floor(10 * Math.random()) ) ); // 修正handlePress的定义方式,函数组件里要用const声明 const handlePress = () => { // 推荐用函数式更新count,避免闭包导致的旧值问题 setCount(prevCount => prevCount + 1); }; return ( <View> <Text style={{ marginTop: 40 }}> you hit {count}! </Text> {/* 用join把数组转成友好的字符串格式 */} <Text style={{ marginTop: 40 }}> this is randomn {randomNoArry.join(', ')}! </Text> {/* 直接传递handlePress即可,无需额外箭头函数 */} <Button style={{ marginTop: 40 }} onPress={handlePress} title="click Me" /> </View> ); } const Game = () => { return ( <> <Game1 randomnno="6" /> </> ); } export default Game;
方案二:使用useMemo缓存数组(适合数组无需后续修改的场景)
useMemo可以缓存计算结果,只有当依赖项变化时才重新计算。我们设置空依赖数组,让数组仅在组件挂载时生成一次:
import React, { useState, useMemo } from "react"; import { Button, Text, View } from "react-native"; const Game1 = (props) => { const [count, setCount] = useState(0); // 用useMemo缓存数组,空依赖确保只生成一次 const randomNoArry = useMemo(() => Array.from( { length: parseInt(props.randomnno) }, () => 1 + Math.floor(10 * Math.random()) ), [] // 空依赖数组 ); const handlePress = () => { setCount(prevCount => prevCount + 1); }; return ( <View> <Text style={{ marginTop: 40 }}> you hit {count}! </Text> <Text style={{ marginTop: 40 }}> this is randomn {randomNoArry.join(', ')}! </Text> <Button style={{ marginTop: 40 }} onPress={handlePress} title="click Me" /> </View> ); } const Game = () => { return ( <> <Game1 randomnno="6" /> </> ); } export default Game;
额外注意点:
props.randomnno是字符串类型(你传的是"6"),需要用parseInt转成数字,否则Array.from的length会失效。- 显示数组时用
join(', ')把数组转成字符串,不然会显示默认的数组对象格式,不够友好。 handlePress要改成const声明的函数,函数组件里不能用类组件的方法写法,否则会报错。- 更新
count时用函数式更新setCount(prevCount => prevCount + 1),避免闭包导致的状态值不更新问题。
内容的提问来源于stack exchange,提问作者Dobin
相关产品推荐
相关产品推荐

