首页 > 解决方案 > React Typescript 钩子和道具

问题描述

这是我第一个使用 Typescript 和 React Native 的项目。我只是在 App.tsx 上创建了一个简单的逻辑,然后我尝试用一​​个组件来拆分它。但是,当我从 Modal 组件传递道具时,我得到一个错误 ts(2322)。我知道代码需要改进,因为这是我第一次使用 Typescript。我不知道是否有人可以帮助我指导我。下面是我做的原始 App.tsx:

import { Button, FlatList, Modal, StyleSheet, Text, TextInput, View } from 'react-native';

import React from 'react';
import { useState } from 'react';

export interface AppProps {
  id: string | number;
  item: string;
  name: string;
  placeholder: string;
  value: string
}
 
const App: React.FC<AppProps> = () => {
  const [textInput, setTextInput] = useState<string>('');
  const [itemList, setItemList] = useState<any[]>([]);

  const [itemSelected, setItemSelected] = useState<any>({});
  const [modalVisible, setModalVisible] = useState<boolean>(false);

  const handlerConfirmDelete = () => {
    setItemList(itemList.filter(item => item.id !== itemSelected.id));
    setItemSelected({});
    setModalVisible(false);
  }

  const handlerModalOpen = (id: string) => {
    setItemSelected(itemList.find(item => item.id === id));
    setModalVisible(true);
  }

  const onHandlerChangeText = (textValue: string) => setTextInput(textValue);
  const handleAddPress = () => {
    setItemList([
      ...itemList,
      {
        id: Math.random().toString(),
        value: textInput,
      },
    ]);
  }
  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>
    <Modal animationType='slide' visible={modalVisible}>
      <View>
        <Text>Borrar</Text>
      </View>
      <View>
        <Text>seguro q borramos?</Text>
      </View>
      <View>
        <Text>{itemSelected.value}</Text>
      </View>
      <View>
        <Button onPress={handlerConfirmDelete} title='Confirm' />
      </View>
    </Modal>
    </>
  );
}

export default App;

这是新的 App.tsx 和 Modal.tsx:App.tsx

import { Button, FlatList, Modal, StyleSheet, Text, TextInput, View } from 'react-native';

import ModalComponent from './components/Modal';
import React from 'react';
import { useState } from 'react';

export interface AppProps {
  id: string | number;
  item: string;
  name: string;
  placeholder: string;
  value: string
}
 
const App: React.FC<AppProps> = () => {
  const [textInput, setTextInput] = useState<string>('');
  const [itemList, setItemList] = useState<any[]>([]);

  const [itemSelected, setItemSelected] = useState<any>({});
  const [modalVisible, setModalVisible] = useState<boolean>(false);

  const handlerConfirmDelete = () => {
    setItemList(itemList.filter(item => item.id !== itemSelected.id));
    setItemSelected({});
    setModalVisible(false);
  }

  const handlerModalOpen = (id: string) => {
    setItemSelected(itemList.find(item => item.id === id));
    setModalVisible(true);
  }

  const onHandlerChangeText = (textValue: string) => setTextInput(textValue);
  const handleAddPress = () => {
    setItemList([
      ...itemList,
      {
        id: Math.random().toString(),
        value: textInput,
      },
    ]);
  }
  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} />
    </>
  );
}

export default App;

模态的.tsx

import { Button, Modal, StyleSheet, Text, View } from "react-native";

import { AppProps } from "../../App";

export interface ModalComponentProps {
    props: AppProps
    
}
 
const ModalComponent: React.FC<ModalComponentProps> = (props: any) => {
    
    const {modalVisible, itemSelected, handlerConfirmDelete} = props;
    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}>{itemSelected.value}</Text>                    
                        <View>
                            <Button onPress={handlerConfirmDelete} title='Confirm' />
                        </View>
                    </View>
                </View>
            </Modal>
        </>
    );
}
export default ModalComponent;

我还没有放置样式,因为我想首先让它正常工作。提前致谢。

这是错误:类型'{ modalVisible:boolean; 项目选择:任何;handlerConfirmDelete: () => 无效;}' 不可分配给类型 'IntrinsicAttributes & ModalComponentProps & { children?: ReactNode; }'。类型'IntrinsicAttributes & ModalComponentProps & { children?: ReactNode; 上不存在属性'modalVisible' }'。

标签: typescriptreact-nativereact-hooksreact-propsreact-typescript

解决方案


这里有一些基础知识:

  1. 如果你使用React.FC<DataType>DataType会自动应用到props组件的 ,但是你已经在 中做props:anyModalComponent,这会绕过编译问题,但它会在以后破坏事情。因此,更改props:anyprops.

提示:只需将鼠标悬停props在 VSCode 中,智能感知就会显示它的数据类型

  1. 您正在使用AppPropsin App.tsxas React.FC<AppProps>,如果将其更改为const App: React.FC<AppProps> = (props) => {...},然后再次悬停props,您可以看到智能感知正在发挥它的魔力,但由于它没有在代码中的任何地方使用,您可以将其删除。

现在回到核心问题,如果你将鼠标悬停在上面,props你可以看到它包含的内容,它只会包含props: AppProps代码中任何地方都没有使用的内容。

而是将其更改为:

interface ModalComponentProps {
   modalVisible: boolean
   itemSelected: any // you have set any in App.tsx
   handlerConfirmDelete: () => void
    
}

它应该可以工作。我仍然认为你会有问题,styles因为我不知道它是从哪里进口的。

我会建议使用object而不是any,或者自定义界面objectany现在会让事情变得容易,以后会咬你。


推荐阅读