React Typescript 钩子和道具

React Typescript hooks and props

这是我第一个使用 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;

Modal.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; itemSelected: 任何; handlerConfirmDelete: () => void; }' 不可分配给类型 'IntrinsicAttributes & ModalComponentProps & { children?: ReactNode; }'。 属性 'modalVisible' 在类型 'IntrinsicAttributes & ModalComponentProps & { children?: ReactNode; }' 上不存在。

这里有一些基础知识:

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

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

  1. 您在App.tsx中使用AppProps作为React.FC<AppProps>,如果将其更改为const App: React.FC<AppProps> = (props) => {...},再次将鼠标悬停在props上,您可以看到intellisense 的作用很神奇,但由于它没有在代码中的任何地方使用,您可以将其删除。

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

改为:

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

它应该可以工作。我仍然认为您对 styles 会有疑问,因为我不知道它是从哪里导入的。

我建议使用 object 而不是 any,或者使用 object 上的自定义界面。 any 暂时让事情变得简单,以后再咬你。