Reputation: 346
This is my first project using Typescript and also React Native. I just create a simple logic on App.tsx then, I tried to split it with a component. But, when I pass the props from the Modal component I get an error ts(2322). I know the code needs to be improve as it is my first time using Typescript. I do not know if someone could help me guiding me about it. Below is the original App.tsx I did:
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;
This is the new App.tsx and the 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;
I haven't put the styles yet as I want first to make it work correctly. Thanks in advance.
This is the error: Type '{ modalVisible: boolean; itemSelected: any; handlerConfirmDelete: () => void; }' is not assignable to type 'IntrinsicAttributes & ModalComponentProps & { children?: ReactNode; }'. Property 'modalVisible' does not exist on type 'IntrinsicAttributes & ModalComponentProps & { children?: ReactNode; }'.
Upvotes: 0
Views: 2061
Reputation: 1496
Some basics here:
React.FC<DataType>
, the DataType
is automatically applied to the props
of the component, but you have done props:any
in ModalComponent
, this would have bypassed the compile issue, but it would break things later on. So, change props:any
to just props
.Tip: Just hover over props
in VSCode, it's intellisense will show you it's datatype
AppProps
in App.tsx
as React.FC<AppProps>
, if you change it to const App: React.FC<AppProps> = (props) => {...}
, and hover over props
again, you can see the intellisense doing it's magic, but since it's not used anywhere in the code, you can remove it.Now on to the core problem, if you hover over props
you can see what it contains, it will only contain props: AppProps
which isn't used anywhere in your code.
Instead change it to :
interface ModalComponentProps {
modalVisible: boolean
itemSelected: any // you have set any in App.tsx
handlerConfirmDelete: () => void
}
and it should work. I still think you will have issue with styles
as I don't know where it is imported from. 🙂
I would recommend to use object
instead of any
, or a custom interface over object
. any
will make things easy for now and bite you later.
Upvotes: 2