You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native中如何从表格渲染随机对象?(记忆游戏洗牌需求)

Fixing Shuffle Logic & Refactoring Your React Native Memory Game

Hey there! Let's get your memory game's shuffle functionality working properly, and also clean up some key issues in your current code that are holding you back.

First, let's address the problems in your existing setup:

  • Your cards state is a string ("[...card]") instead of an actual array of card data. We need to store your card values/objects in a proper array to shuffle them.
  • Using duplicate ref="card" won't work—refs need unique identifiers, and more importantly, we should use data-driven rendering instead of relying on refs for your cards.
  • Your placeholder shuffle function needs a tailored implementation for memory game cards (which usually require matching pairs) that deviates from the standard JS shuffle.

Step 1: Implement a Custom Non-Standard Shuffle Function

You mentioned avoiding the "standard JS shuffle"—let's use a modified Fisher-Yates (Knuth) shuffle that adds an extra layer of randomness, plus builds paired card data perfect for a memory game:

// Custom shuffle with extra randomization twist
_shuffleCards = () => {
  // Create paired card values (adjust quantity/values as needed)
  const cardValues = [1, 2, 3, 4, 1, 2, 3, 4];
  let shuffled = [...cardValues];
  
  for (let i = shuffled.length - 1; i > 0; i--) {
    // Standard Fisher-Yates swap
    const j = Math.floor(Math.random() * (i + 1));
    [shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];
    
    // Extra random swap 30% of the time for non-standard behavior
    if (Math.random() < 0.3) {
      const k = Math.floor(Math.random() * (i + 1));
      [shuffled[i], shuffled[k]] = [shuffled[k], shuffled[i]];
    }
  }
  
  return shuffled;
};

Step 2: Refactor Your Component for Data-Driven Rendering

We'll rewrite your component to use the shuffled card array to render the grid dynamically, instead of hardcoding rows. This makes shuffling and updating cards trivial:

import React from 'react'
import { StyleSheet, View, Text, TouchableOpacity } from 'react-native'
import { Col, Row, Grid } from "react-native-easy-grid";

export default class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      color: "red",
      cards: [] // Empty array to hold shuffled card data
    }
  }

  // Custom shuffle function with extra randomization
  _shuffleCards = () => {
    const cardValues = [1, 2, 3, 4, 1, 2, 3, 4];
    let shuffled = [...cardValues];
    
    for (let i = shuffled.length - 1; i > 0; i--) {
      const j = Math.floor(Math.random() * (i + 1));
      [shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];
      
      // Extra random swap to deviate from standard shuffle
      if (Math.random() < 0.3) {
        const k = Math.floor(Math.random() * (i + 1));
        [shuffled[i], shuffled[k]] = [shuffled[k], shuffled[i]];
      }
    }
    
    return shuffled;
  }

  componentDidMount() {
    // Initialize shuffled cards when component loads
    this.setState({ cards: this._shuffleCards() });
  }

  _test = () => {
    this.setState({ color: this.state.color === "red" ? "blue" : "red" });
  }

  // Helper to render rows dynamically from card data
  renderRows = () => {
    const { cards } = this.state;
    const rows = [];
    
    // Split cards into individual rows (matches your 1-column grid)
    for (let i = 0; i < cards.length; i++) {
      rows.push(
        <Row key={i}>
          <TouchableOpacity onPress={this._test} style={styles.card}>
            <Text style={styles.cardText}>{cards[i]}</Text>
          </TouchableOpacity>
        </Row>
      );
    }
    return rows;
  }

  render() {
    return (
      <View style={styles.container}>
        <Grid>
          <Col>
            {this.renderRows()}
          </Col>
        </Grid>
        <View style={styles.colorIndicator}>
          <Text style={{ color: this.state.color }}>XXX</Text>
        </View>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
    padding: 20,
  },
  card: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    borderWidth: 1,
    borderColor: '#ccc',
    margin: 5,
    padding: 15,
    borderRadius: 8,
  },
  cardText: {
    fontSize: 18,
    fontWeight: '500',
  },
  colorIndicator: {
    marginTop: 20,
    fontSize: 24,
  },
});

Key Improvements Explained:

  • Data-Driven Rendering: Rows are generated dynamically from the shuffled cards array, so shuffling only requires updating the state array—no messy refs needed.
  • Custom Shuffle: The extra random swap step makes this implementation different from the standard Fisher-Yates shuffle, as you requested.
  • Clean State: We store actual card data in the state instead of strings, making the component far more maintainable.
  • Better Styling: Added basic card styling to make the game board more intuitive.

If you want to expand the game (e.g., add card images, unique IDs, or flip functionality), you can modify the cardValues array to hold objects instead of numbers (like [{ id: 1, value: '🍎' }, { id: 2, value: '🍎' }, ...]).

内容的提问来源于stack exchange,提问作者Roland Doe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:13:00