In my code, I take an input from the user, run a graphql query and then conditionally render some items according to the results (via showUsers functions). However, instead of using showUsers here as a function, I want to make it a separate component where I can pass userData.
export const AddContactTry: React.FunctionComponent = () => { const validationSchema = phoneNumberValidationSchema; const { values, handleChange, handleSubmit, dirty, handleBlur, isValid, resetForm, isSubmitting, setSubmitting, touched}= useFormik({ initialValues: { phoneNumber: '', }, validationSchema, onSubmit: (values: FormValues) => { handleSubmitForm(values); }, }); const [isSubmitted, setIsSubmitted] = useState(false); const [userData, setUserData] = useState<UsersLazyQueryHookResult>(''); const navigation = useNavigation(); //const validationSchema = phoneNumberValidationSchema; const [ createUserRelationMutation, { data: addingContactData, loading: addingContactLoading, error: addingContactError, called: isMutationCalled, }, ] = useCreateUserRelationMutation({ onCompleted: () => { Alert.alert('Contact Added'); }, }); const showUsers = React.useCallback( (data: UsersLazyQueryHookResult) => { if (data) { return (<View style={styles.users}> {data.users.nodes.map( (item: { firstName: string; lastName: string; id: number }) => { const userName = item.firstName .concat('') .concat(item.lastName); return (<View style={styles.item} key={item.id}><Thumbnail style={styles.thumbnail} source={{ uri:'https://cdn4.iconfinder.com/data/icons/avatars-xmas-giveaway/128/afro_woman_female_person-512.png', }}></Thumbnail><Text style={styles.userName}>{userName}</Text><View style={styles.addButtonContainer}><Button rounded style={styles.addButton} onPress={() => { addContact(Number(item.id)); setIsSubmitted(false); setUserData(null); }}><Icon name="plus" size={moderateScale(20)} color="black" /></Button></View></View> ); }, )}</View> ); } }, [createUserRelationMutation, userData], ); const addContact = React.useCallback( (id: Number) => { console.log('Whats the Id', id); createUserRelationMutation({ variables: { input: { relatedUserId: id, type: RelationType.Contact, userId: 30 }, }, }); }, [createUserRelationMutation], ); const getContactId = React.useCallback( (data: UsersLazyQueryHookResult) => { //resetForm(); if (data) { if (data.users.nodes.length == 0) { Alert.alert('No User Found'); } else { setUserData(data); } } }, [addContact], ); const [loadUsers] = useUsersLazyQuery({ onCompleted: getContactId, onError: _onLoadUserError, }); const handleSubmitForm = React.useCallback( (values: FormValues) => { setIsSubmitted(true); const plusSign = '+'; const newPhoneNumber = plusSign.concat(values.phoneNumber); console.log('Submitted'); loadUsers({ variables: { where: { phoneNumber: newPhoneNumber }, }, }); resetForm(); }, [loadUsers], ); return (<SafeAreaView><View style={styles.container}><View style={styles.searchTopContainer}><View><View style={styles.searchFieldContainer}><View style={styles.form}><Item underline style={styles.newFieldInput} ><Icon name="mobile" color="black" size={26}></Icon><Input onChangeText={handleChange('phoneNumber') as (text: string) => void} onBlur={handleBlur('phoneNumber') as (event: any) => void} value={values.phoneNumber} placeholder="49152901820" /></Item></View><View style={styles.buttonContainer}><Button block success disabled={!isValid || !dirty} onPress={handleSubmit} style={styles.button}><Text>Speichern</Text></Button></View></View></View> {isSubmitted && showUsers(userData)}</View></View> {/* <User data={userData}></User> */}</SafeAreaView> );};
Currently, the rendering happens here:
{isSubmitted && showUsers(userData)}
Now, to move the rendering to a separate component, I tried to do this. Currently, this works:
export const AddContactTry: React.FunctionComponent = () => { const validationSchema = phoneNumberValidationSchema; const { values, handleChange, handleSubmit, dirty, handleBlur, isValid, resetForm, isSubmitting, setSubmitting, touched}= useFormik({ initialValues: { phoneNumber: '', }, validationSchema, onSubmit: (values: FormValues) => { handleSubmitForm(values); }, }); const [isSubmitted, setIsSubmitted] = useState(false); const [userData, setUserData] = useState<UsersLazyQueryHookResult>(''); const navigation = useNavigation(); const _onLoadUserError = React.useCallback((error: ApolloError) => { Alert.alert('Oops, try again later'); }, []); // const [ // createUserRelationMutation, // { // data: addingContactData, // loading: addingContactLoading, // error: addingContactError, // called: isMutationCalled, // }, // ] = useCreateUserRelationMutation({ // onCompleted: () => { // Alert.alert('Contact Added'); // }, // }); // const showUsers = React.useCallback( // (data: UsersLazyQueryHookResult) => { // if (data) { // return ( // <View style={styles.users}> // {data.users.nodes.map( // (item: { firstName: string; lastName: string; id: number }) => { // const userName = item.firstName // .concat('') // .concat(item.lastName); // return ( // <View style={styles.item} key={item.id}> // <Thumbnail // style={styles.thumbnail} // source={{ // uri: // 'https://cdn4.iconfinder.com/data/icons/avatars-xmas-giveaway/128/afro_woman_female_person-512.png', // }}></Thumbnail> // <Text style={styles.userName}>{userName}</Text> // <View style={styles.addButtonContainer}> // <Button // rounded // style={styles.addButton} // onPress={() => { // //addContact(Number(item.id)); // setIsSubmitted(false); // setUserData(null); // }}> // <Icon // name="plus" // size={moderateScale(20)} // color="black" // /> // </Button> // </View> // </View> // ); // }, // )} // </View> // ); // } // }, // [createUserRelationMutation, userData], // ); // const addContact = React.useCallback( // (id: Number) => { // console.log('Whats the Id', id); // createUserRelationMutation({ // variables: { // input: { relatedUserId: id, type: RelationType.Contact, userId: 30 }, // }, // }); // }, // [createUserRelationMutation], // ); const getContactId = React.useCallback( (data: UsersLazyQueryHookResult) => { //resetForm(); if (data) { if (data.users.nodes.length == 0) { Alert.alert('No User Found'); } else { setUserData(data); } } }, //[addContact], [], ); const [loadUsers] = useUsersLazyQuery({ onCompleted: getContactId, onError: _onLoadUserError, }); const handleSubmitForm = React.useCallback( (values: FormValues) => { setIsSubmitted(true); const plusSign = '+'; const newPhoneNumber = plusSign.concat(values.phoneNumber); loadUsers({ variables: { where: { phoneNumber: newPhoneNumber }, }, }); resetForm(); }, [loadUsers], ); // if (!addingContactLoading && isMutationCalled) { // if (addingContactError) { // Alert.alert('Unable to Add Contact'); // } // } return (<SafeAreaView><View style={styles.container}><View style={styles.searchTopContainer}><View><View style={styles.searchFieldContainer}><View style={styles.form}><Item underline style={styles.newFieldInput} ><Icon name="mobile" color="black" size={26}></Icon><Input onChangeText={handleChange('phoneNumber') as (text: string) => void} onBlur={handleBlur('phoneNumber') as (event: any) => void} value={values.phoneNumber} placeholder="49152901820" /></Item></View><View style={styles.buttonContainer}><Button block success disabled={!isValid || !dirty} onPress={handleSubmit} style={styles.button}><Text>Speichern</Text></Button></View></View></View> {/* {isSubmitted && showUsers(userData)} */}<User data={userData}></User></View></View></SafeAreaView> );};
type UserProps = { data: UsersLazyQueryHookResult; //isSubmitted: boolean; }; export const User: React.FunctionComponent<UserProps> = ({ data, //isSubmitted, }) => {console.log('user called'); const [ createUserRelationMutation, { data: addingContactData, loading: addingContactLoading, error: addingContactError, called: isMutationCalled, }, ] = useCreateUserRelationMutation({ onCompleted: () => { Alert.alert('Contact Added'); }, }); const addContact = React.useCallback( (id: Number) => { console.log('Whats the Id', id); createUserRelationMutation({ variables: { input: { relatedUserId: id, type: RelationType.Contact, userId: 30 }, }, }); }, [createUserRelationMutation], ); if (!addingContactLoading && isMutationCalled) { if (addingContactError) { Alert.alert('Unable to Add Contact'); } } //if (isSubmitted){ if(!data) return null; return (<View style={styles.users}> {data.users.nodes.map( (item: { firstName: string; lastName: string; id: number }) => { const userName = item.firstName .concat('') .concat(item.lastName); return (<View style={styles.item} key={item.id}><Thumbnail style={styles.thumbnail} source={{ uri:'https://cdn4.iconfinder.com/data/icons/avatars-xmas-giveaway/128/afro_woman_female_person-512.png', }}></Thumbnail><Text style={styles.userName}>{userName}</Text><View style={styles.addButtonContainer}><Button rounded style={styles.addButton} onPress={() => { addContact(Number(item.id)); //setIsSubmitted(false); //setUserData(null); }}><Icon name="plus" size={moderateScale(20)} color="black" /></Button></View></View> ); }, )}</View> );}
But I have commented out setIsSubmitted(false);
and setUserData(null);
in the User
component. How can I pass them such that they'll be updated in the original screen too?
Or is there a better way with which I can move out only the rendering list?