React Native拆分Modal组件传props报TS2322错误如何解决
问题根因
你遇到的ts(2322)报错是因为Modal组件的props类型定义和实际传入的属性不匹配,具体有2个核心错误:
- 你定义的
ModalComponentProps接口里只声明了一个叫props的属性,没有声明你实际传入的modalVisible/itemSelected/handlerConfirmDelete三个属性,TS找不到对应属性就会抛错。 - 原本的
AppProps定义错误,App组件本身没有接收外部传入的这些属性,这个接口其实是你列表单个条目的类型,不应该作为App的泛型参数。
修复后的代码
第一步:修改App.tsx
首先修正类型定义,把列表项类型单独抽出来,移除App组件不需要的泛型:
import { Button, FlatList, StyleSheet, Text, TextInput, View } from 'react-native'; import ModalComponent from './components/Modal'; import React from 'react'; import { useState } from 'react'; // 单独定义列表项的类型,替换原来错误的AppProps export interface ListItem { id: string; value: string; } // App本身没有接收外部props,不需要加泛型 const App = () => { const [textInput, setTextInput] = useState<string>(''); // 用ListItem代替any,类型更安全 const [itemList, setItemList] = useState<ListItem[]>([]); const [itemSelected, setItemSelected] = useState<ListItem | {}>({}); const [modalVisible, setModalVisible] = useState<boolean>(false); const handlerConfirmDelete = () => { if ('id' in itemSelected) { setItemList(itemList.filter(item => item.id !== itemSelected.id)); } setItemSelected({}); setModalVisible(false); } const handlerModalOpen = (id: string) => { const selected = itemList.find(item => item.id === id); if (selected) { setItemSelected(selected); setModalVisible(true); } } const onHandlerChangeText = (textValue: string) => setTextInput(textValue); const handleAddPress = () => { setItemList([ ...itemList, { id: Math.random().toString(), value: textInput, }, ]); // 添加后自动清空输入框,可选调整 setTextInput(''); } return ( <> <View style={styles.container}> <View style={styles.firstInputs}> <TextInput placeholder='Item de Lista' onChangeText={onHandlerChangeText} value={textInput} /> <Button title='Add' onPress={handleAddPress} /> </View> <View> <FlatList data={itemList} keyExtractor={(item) => item.id} renderItem={(data) => ( <View> <Text>{data.item.value}</Text> <Button title='X' onPress={() => handlerModalOpen(data.item.id)} /> </View> )} /> </View> </View> <ModalComponent modalVisible={modalVisible} itemSelected={itemSelected} handlerConfirmDelete={handlerConfirmDelete} /> </> ); } // 补充基础样式避免运行报错,可后续自行调整 const styles = StyleSheet.create({ container: { padding: 30, marginTop: 50, }, firstInputs: { flexDirection: 'row', gap: 10, marginBottom: 20, alignItems: 'center' } }) export default App;
第二步:修改Modal.tsx
重新定义Modal组件的props类型,和实际传入的属性对齐:
import { Button, Modal, StyleSheet, Text, View } from "react-native"; // 注意修改为你实际的App.tsx相对路径 import { ListItem } from "../App"; // 明确声明所有传入的属性类型 export interface ModalComponentProps { modalVisible: boolean; itemSelected: ListItem | {}; handlerConfirmDelete: () => void; } const ModalComponent = ({modalVisible, itemSelected, handlerConfirmDelete}: ModalComponentProps) => { return ( <> <Modal animationType='slide' visible={modalVisible}> <View style={styles.modalContainer}> <View style={[styles.modalContent, styles.shadow]}> <Text style={styles.modalMessage}>Seguro deseas borrar?</Text> <Text style={styles.modalTitle}>{'value' in itemSelected ? itemSelected.value : ''}</Text> <View> <Button onPress={handlerConfirmDelete} title='Confirm' /> </View> </View> </View> </Modal> </> ); } // 补充基础样式避免运行报错,可后续自行调整 const styles = StyleSheet.create({ modalContainer: { flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: 'rgba(0,0,0,0.5)' }, modalContent: { backgroundColor: 'white', padding: 30, borderRadius: 10, gap: 20, alignItems: 'center' }, shadow: { shadowColor: '#000', shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.25, shadowRadius: 4, elevation: 5 }, modalMessage: { fontSize: 18 }, modalTitle: { fontSize: 22, fontWeight: 'bold' } }) export default ModalComponent;
补充说明
- 移除了不必要的
any类型,所有属性都有明确的类型约束,后续开发不会出现隐式any的报错 - 增加了空值判断,避免选中条目为空时渲染报错
- 补充了基础样式,可直接运行测试逻辑,后续可根据需求调整样式
内容的提问来源于stack exchange,提问作者Joaquin Palacios
相关产品推荐
相关产品推荐

