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

React Native中如何将选中的自定义复选框数据传递到下一页?

实现选中复选框名称的跨页面传递

问题描述

我已创建可切换的自定义复选框,并将其与名称一同渲染在FlatList组件中,现在希望通过React Navigation把选中复选框对应的名称传递到下一个页面,该如何实现?

现有代码

自定义复选框组件

import React from "react";
import { TouchableOpacity, View } from "react-native";
import { useState } from "react";
import IconAntDesign from "react-native-vector-icons/AntDesign";

export function CheckBoxCustom() {
  const [count, setCount] = useState(0);
  return (
    <View>
      <TouchableOpacity
        style={{
          backgroundColor: "white",
          width: 20,
          height: 20,
          borderWidth: 2,
          borderColor: "#ddd",
        }}
        onPress={() => setCount(!count)}
      >
        {count ? (
          <IconAntDesign name="check" size={15} color="black" />
        ) : null}
      </TouchableOpacity>
    </View>
  );
}

FlatList所在页面

import React, {useState} from 'react';
import {
  SafeAreaView,
  Text,
  View,
  Image,
  StyleSheet,
  FlatList,
  Dimensions,
  useWindowDimensions,
  ScrollView,
  Button,
} from 'react-native';
import Header from '../CustomComponents/RestaurentUI/Header';
import {CheckBoxCustom} from '../CustomComponents/RestaurentUI/Checkbox';
import {TabView, SceneMap, TabBar} from 'react-native-tab-view';
import {useNavigation} from '@react-navigation/native';
import GetCheckBoxData from './GetCheckBoxData';

const data = [
  {name: 'Lumlère brûlée', status: 'Problems'},
  {name: 'Aucune eau chaude', status: 'Problems'},
  {name: 'Lumlère brûlée', status: 'Problems'},
  {name: 'Service de ménage', status: 'Problems'},
  {name: 'AC non-fonctionnel', status: 'Problems'},
  {name: 'WIFI non-fonctionnel', status: 'Problems'},
  {name: 'Four non-fonctionnel', status: 'Problems'},
];

const renderItem = ({item, index}) => {
  return (
    <View>
      <View style={{flexDirection: 'row'}}>
        <CheckBoxCustom />
        <Text style={{marginLeft: 10}}>{item.name} </Text>
      </View>
    </View>
  );
};

const separator = () => {
  return (
    <View
      style={{
        height: 1,
        backgroundColor: '#f1f1f1',
        marginBottom: 12,
        marginTop: 12,
      }}
    />
  );
};

const FirstRoute = () => (
  <FlatList
    style={{marginTop: 20}}
    data={data}
    keyExtractor={(e, i) => i.toString()}
    renderItem={renderItem}
    ItemSeparatorComponent={separator}
  />
);

const SecondRoute = () => (
  <View style={[styles.scene, {backgroundColor: 'white'}]} />
);

const initialLayout = {width: Dimensions.get('window').width};

const renderScene = SceneMap({
  first: FirstRoute,
  second: SecondRoute,
});

const ReportScreen = ({navigation}) => {
  const nav = useNavigation();
  const layout = useWindowDimensions();
  const [index, setIndex] = useState(0);
  const [routes] = useState([
    {key: 'first', title: 'Problemes'},
    {key: 'second', title: 'Besoins complémentaitaires'},
  ]);

  const goToScreen = () => {
    navigation.navigate('GetCheckBoxData', {title: 'Hii all'});
  };
  const [checked, setChecked] = useState({});

  const checkToggle = id => {
    setChecked(checked => ({
      ...checked,
      [id]: !checked[id],
    }));
  };

  return (
    <SafeAreaView style={styles.safearea}>
      <Header title="Report" />
      <ScrollView showsVerticalScrollIndicator={false} bounces={false}>
        <View style={{flexDirection: 'row', marginTop: 20}}>
          <View style={{flex: 1, height: 1, backgroundColor: '#ccc'}} />
        </View>
        <View style={styles.cardView}>
          <View style={styles.subView}>
            <Image
              style={styles.image}
              source={require('../Assets/UIPracticeImage/H1.jpg')}
            />
            <View style={styles.internalSubView}>
              <View style={styles.nameView}>
                <Text style={styles.nameText}>Pine Hill Green Caban</Text>
              </View>
              <View style={styles.dateView}>
                <Text style={styles.dateText}>May 22-27</Text>
              </View>
            </View>
          </View>
        </View>
        <View style={{flexDirection: 'row'}}>
          <View style={{flex: 1, height: 1, backgroundColor: '#ccc'}} />
        </View>
        <View
          style={{flex: 1, height: 385, width: '100%'}}>
          <TabView
            navigationState={{index, routes}}
            renderScene={renderScene}
            onIndexChange={setIndex}
            initialLayout={initialLayout}
            style={styles.container}
            renderTabBar={props => (
              <TabBar
                tabStyle={{alignItems: 'flex-start', width: 'auto'}}
                {...props}
                renderLabel={({route, color}) => (
                  <Text style={{color: 'black'}}>{route.title}</Text>
                )}
                style={{backgroundColor: 'white'}}
              />
            )}
          />
        </View>

        <Button title="Click me" onPress={goToScreen} />
      </ScrollView>
    </SafeAreaView>
  );
};

export default ReportScreen;

const styles = StyleSheet.create({
  safearea: {marginHorizontal: 20},
  cardView: {borderRadius: 10, marginVertical: 10, paddingVertical: 8},
  subView: {flexDirection: 'row'},
  image: {height: 80, width: 110, borderRadius: 10},
  internalSubView: {justifyContent: 'space-between', flex: 1},
  nameView: {justifyContent: 'space-between', flexDirection: 'row', alignItems: 'center', marginLeft: 10},
  nameText: {fontWeight: 'bold', width: '45%', fontSize: 15},
  dateView: {flexDirection: 'row', alignItems: 'center', marginLeft: 10, justifyContent: 'space-between'},
  dateText: {width: 80},
  container: {marginTop: 20},
  scene: {flex: 1},
});

解决方案

核心思路是将复选框的状态提升到父组件统一管理,再在跳转时筛选选中项并传递,具体步骤如下:

1. 修改自定义复选框组件

移除组件内部的状态,改为接收外部传入的选中状态和点击回调:

import React from "react";
import { TouchableOpacity, View } from "react-native";
import IconAntDesign from "react-native-vector-icons/AntDesign";

export function CheckBoxCustom({ isChecked, onToggle }) {
  return (
    <View>
      <TouchableOpacity
        style={{
          backgroundColor: "white",
          width: 20,
          height: 20,
          borderWidth: 2,
          borderColor: "#ddd",
          justifyContent: "center",
          alignItems: "center"
        }}
        onPress={onToggle}
      >
        {isChecked ? (
          <IconAntDesign name="check" size={15} color="black" />
        ) : null}
      </TouchableOpacity>
    </View>
  );
}

2. 传递状态到FlatList列表项

调整FirstRoute为接收props的函数,将父组件的选中状态和回调传递给每个复选框:

// 修改FirstRoute,接收父组件状态和回调
const FirstRoute = ({ checked, checkToggle }) => (
  <FlatList
    style={{ marginTop: 20 }}
    data={data}
    keyExtractor={(e, i) => i.toString()}
    renderItem={({ item, index }) => (
      <View style={{flexDirection: 'row', alignItems: 'center'}}>
        <CheckBoxCustom
          isChecked={checked[index] || false}
          onToggle={() => checkToggle(index)}
        />
        <Text style={{marginLeft: 10}}>{item.name} </Text>
      </View>
    )}
    ItemSeparatorComponent={separator}
  />
);

// 修改renderScene,传递父组件的状态和回调
const renderScene = SceneMap({
  first: (props) => <FirstRoute {...props} checked={checked} checkToggle={checkToggle} />,
  second: SecondRoute,
});

3. 筛选选中名称并传递到下一页

修改goToScreen函数,先筛选选中项的名称,再通过navigation传递:

const goToScreen = () => {
  // 筛选所有选中项的名称
  const selectedNames = data.filter((_, index) => checked[index]).map(item => item.name);
  // 传递到目标页面
  navigation.navigate('GetCheckBoxData', { selectedNames });
};

4. 目标页面接收数据

在GetCheckBoxData页面中,通过route.params获取传递的选中名称:

// GetCheckBoxData.js示例代码
import React from 'react';
import { View, Text, SafeAreaView } from 'react-native';

const GetCheckBoxData = ({ route }) => {
  const { selectedNames } = route.params;

  return (
    <SafeAreaView style={{flex:1, padding:20}}>
      <Text style={{fontSize:16, fontWeight:'bold', marginBottom:10}}>选中的问题:</Text>
      {selectedNames.map((name, index) => (
        <Text key={index} style={{marginVertical:4}}>- {name}</Text>
      ))}
    </SafeAreaView>
  );
};

export default GetCheckBoxData;

关键说明

  • 状态提升:将复选框状态从组件内部移到父组件,便于统一管理所有选中状态,后续筛选和传递更便捷。
  • 标识稳定性:示例中用列表项的index作为选中状态的key,若数据可能动态变化,建议给data数组添加唯一id字段替代index。
  • 导航传参:React Navigation通过navigation.navigate的第二个参数传递数据,目标页面通过route.params接收。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 00:36:26