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

React Native实现选中元素移动至另一数组后移除原数组对应元素

解决元素跨数组移动后原数组移除的问题

你当前的实现有几个核心问题导致样式隐藏失效,而且逻辑不严谨:

  • 通过e._dispatchInstances.memoizedProps.children获取选中内容是React内部属性,不稳定且不推荐使用
  • setMoveSelectedWord里直接用selectedWord会因为状态异步更新拿不到最新值
  • 用样式隐藏只是视觉上让元素消失,元素依然存在于原数组的渲染列表中,没有真正从数据源移除

下面是正确的实现方式,核心是维护两个独立的数组状态,移动元素时直接修改数组内容,确保原数组彻底移除目标元素,反之亦然:

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

// 初始数据源
const initialWords = [
  { id: 1, word: 'item-1' },
  { id: 2, word: 'item-2' },
  { id: 3, word: 'item-3' },
  { id: 4, word: 'item-4' },
];

const HomeScreen = () => {
  // 原数组(可移动的源区域)
  const [sourceWords, setSourceWords] = useState(initialWords);
  // 目标数组(已移动的元素区域)
  const [targetWords, setTargetWords] = useState([]);

  // 把元素从源数组移到目标数组
  const handleMoveToTarget = (selectedItem) => {
    setSourceWords(prev => prev.filter(item => item.id !== selectedItem.id));
    setTargetWords(prev => [...prev, selectedItem]);
  };

  // 把元素从目标数组移回源数组
  const handleMoveBackToSource = (selectedItem) => {
    setTargetWords(prev => prev.filter(item => item.id !== selectedItem.id));
    setSourceWords(prev => [...prev, selectedItem]);
  };

  return (
    <View style={styles.container}>
      {/* 目标区域 */}
      <View style={styles.placeholder}>
        <Text style={styles.title}>已移动元素</Text>
        {targetWords.map(item => (
          <Text
            key={item.id}
            style={styles.targetItem}
            onPress={() => handleMoveBackToSource(item)}
          >
            {item.word}
          </Text>
        ))}
      </View>

      {/* 源区域 */}
      <View style={styles.placeholder}>
        <Text style={styles.title}>可移动元素</Text>
        <View style={styles.sourceRow}>
          {sourceWords.map(item => (
            <Text
              key={item.id}
              style={styles.sourceItem}
              onPress={() => handleMoveToTarget(item)}
            >
              {item.word}
            </Text>
          ))}
        </View>
      </View>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    padding: 20,
    gap: 20,
  },
  placeholder: {
    padding: 15,
    borderWidth: 1,
    borderColor: '#ccc',
    borderRadius: 8,
  },
  title: {
    fontSize: 16,
    fontWeight: 'bold',
    marginBottom: 10,
  },
  sourceRow: {
    flexDirection: 'row',
    flexWrap: 'wrap',
    gap: 10,
  },
  sourceItem: {
    padding: 8,
    backgroundColor: '#f0f0f0',
    borderRadius: 4,
  },
  targetItem: {
    padding: 8,
    backgroundColor: '#e6f7ff',
    borderRadius: 4,
    marginBottom: 5,
  },
});

export default HomeScreen;

关键实现说明

  • 用id作为唯一标识过滤数组,比直接对比word更可靠,避免重复内容导致的逻辑错误
  • 移动元素时直接修改两个数组的状态,确保源数组彻底移除元素、目标数组添加元素,双向移动逻辑完整
  • 渲染时直接基于两个状态数组生成内容,不需要用样式隐藏,元素不在对应数组里就不会被渲染
  • 点击目标区域的元素可直接移回源区域,完全符合你需要的双向移动需求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 22:01:17