How to pass a already implemented Component inside the Copilot Step in react-native-copilot - react-native

I am trying to built a guided tour for my app using react native copilot
https://github.com/okgrow/react-native-copilot
and i cannot figure out how to use a already built component inside the its CopilotSteps as mentioned in the tutorial.
This is the my code so far and it gives me the following error
<CopilotStep
text="This is a hello world example!"
order={1}
name="hello"
>
{({ copilot }) => (
<Card snow to={`${basePath}/account`} {...copilot}>
<Row inline justify="center" fluid>
<Block inline justify="center">
<FIcon name="shield" size={25} />
</Block>
<Block justify="center">
<P compact>Account and Security</P>
<P compact small helper>
Edit Your Account Information
</P>
</Block>
<Block inline justify="center">
<FIcon name="chevron-right" size={25} />
</Block>
</Row>
</Card>
)}
</CopilotStep>
error =>
D:\My Work\Company Projects\Ongoing\ZappyFoods\Mobile App\zappyfood_app\node_modules\react-native\Libraries\Core\ExceptionsManager.js:63 Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
what should i do to get this code run proerly

You have to make the component "walkthroughable", so for example if my original component was a simple TouchableOpacity button.
<TouchableOpacity
onPress={this.callFunction}
>
<Icon name="photo" type="FontAwesome" />
</TouchableOpacity>
Then to make it work with copilot first import walkthroughable.
import {
copilot,
walkthroughable,
CopilotStep
} from "#okgrow/react-native-copilot";
Then call the walkthroughable function passing our TouchableOpacity component.
const WalkthroughableTouchableOpacity = walkthroughable(TouchableOpacity);
Finally add the copilot step and use the new Walkthroughable component in place where you would've used TouchableOpacity.
<CopilotStep
text="Hey! This is the first step of the tour!"
order={1}
name="openApp"
>
<WalkthroughableTouchableOpacity
onPress={this.callFunction}
>
<Icon name="photo" type="FontAwesome" />
</WalkthroughableTouchableOpacity>
</CopilotStep>
So the entire file could look like
import {
copilot,
walkthroughable,
CopilotStep
} from "#okgrow/react-native-copilot";
import { Icon } from "native-base";
import React, { Component } from "react";
import { TouchableOpacity } from "react-native";
const WalkthroughableTouchableOpacity = walkthroughable(TouchableOpacity);
class Example extends Component {
componentDidMount = async () => {
this.props.copilotEvents.on("stepChange", () => {});
this.props.start();
};
callFunction = () => {
console.log("Button Pressed.");
};
render() {
return (
<CopilotStep
text="Hey! This is the first step of the tour!"
order={1}
name="openApp"
>
<WalkthroughableTouchableOpacity onPress={this.callFunction}>
<Icon name="photo" type="FontAwesome" />
</WalkthroughableTouchableOpacity>
</CopilotStep>
);
}
}
export default copilot({
animated: true,
overlay: "svg"
})(Example);

Related

(Render Error) Element type is invalid: expected a string(for built-in components)or a class/function(for composite components) but got: undefined

i am trying to learn react native but i faced with this error:
Element type is invalid: expected a string(for built-in components)or a class/function(for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in or you might hace mixed up default and named imports.
Check the render method of 'GoalInput'(I am sure i didn't made a typo first'l' and after that 'i' letter)
my App.js code:
import { useState } from "react";
import { StyleSheet, View, FlatList, Button } from "react-native";
import { StatusBar } from "expo-status-bar";
import GoalItem from "./components/GoalItem";
import GoalInput from "./components/GoalInput";
return (
<>
<StatusBar/>
<View>
<Button onPress={startAddGoalHandler}/>
<GoalInput
visible={modalIsVisible}
onAddGoal={addGoalHandler}
onCancel={endAddGoalHandler}
/>
</View>
</>
);
my GoalInput.js code:
import { useState } from "react";
import { StyleSheet,Button,TextInput,View,Model,Image} from "react-native";
const GoalInput = (props) => {
const [enteredGoalText, setEnteredGoalText] = useState("");
const goalInputHandler = (enteredText) => {
setEnteredGoalText(enteredText);
};
const addGoalHandler = () => {
props.onAddGoal(enteredGoalText);
setEnteredGoalText("");
};
return (
<Model visible={props.visible} animationType="slide">
<View>
<Image
source={require("../assets/Images/goal.png")}
/>
<TextInput
onChangeText={goalInputHandler}
value={enteredGoalText}
/>
<View>
<View>
<Button title="Add Goal" onPress={addGoalHandler} color="#b180f0" />
</View>
<View>
<Button title="Cancel" onPress={props.onCancel} color="#f31282" />
</View>
</View>
</View>
</Model>
);
};
export default GoalInput;
I have deleted the style parts for keep question simple and even i search a lot couldn't find the error source on my own thanks for all the attention.
by the way i am using 'expo'
There's no Model in react native , its Modal
SO chnage this first :
import { StyleSheet,Button,TextInput,View,Modal,Image} from "react-native";
And also where youve used in
return(
<Modal>
</Modal>
)
Hope it helps. feel free for doubts

How to implement onPress in menu.item? native-base#3.2.1-rc.1

For some reason there's no nativeBase api or documentation on this. I can not get a menu.item to respond to press/click no matter what I try.
Attempts
putting Text/Button elements from react-native into the menu. item
putting the menu in multiple different screens
creating a separate function instead of just arrow function
import React from "react"
import {
Menu,
HamburgerIcon,
Box,
Center,
NativeBaseProvider,
usePropsResolution,
Text,
Pressable
} from "native-base"
import {Alert, } from "react-native";
import { logout } from "../_redux/_actions/authentication.actions";
export const NavMenu = (props) => {
const menuItems = ['Profile','Sign Out'];
return (
<Box h="80%" w="95%" alignItems="flex-start">
<Menu w="150" top="-85" h="100%"
trigger={(triggerProps) => {
return (
<Pressable accessibilityLabel="More options menu" {...triggerProps}>
<HamburgerIcon color="black" />
</Pressable>
)
}}
>
**<Menu.Item onPress={()=>alert("Alert Title")}>**
Logout
</Menu.Item>
</Menu>
</Box>
)
}
export default () => {
return (
<NativeBaseProvider>
<Center flex={1} px="1">
<NavMenu />
</Center>
</NativeBaseProvider>
)
}
I found workaround around this problem. Would be interested in better solution, but this should work (it is also not very clean solution):
<Menu.Item onPress={()=>alert("Alert Title")}>
<Pressable onPress={()=>alert("Alert Title")}><Text>Logout</Text></Pressable>
</Menu.Item>
Basically what I am doing here is putting onPress to the Menu.Item and then same onPress to the child. You can use this approach for more complicated situations like adding button to the menu like this:
<Menu.Group title="Účet">
<Menu.Item onPress={() => console.log('log')}>
<Button colorScheme="red" onPress={() => console.log('log')} leftIcon={<Icon size="s" as={<MaterialIcons name='logout' />} />}>
Logout
</Button>
</Menu.Item>
</Menu.Group>

One form, but different state

I'm moving now from other technologies to React Native and I have a problem. I have one presentational component which is <TaskInput />.
const TaskInput = (props: ITaskInputProps) => {
return (
<View style={styles.container} >
<Text style={styles.title}>{props.title}</Text>
<TextInput
style={styles.input}
multiline
scrollEnabled={false}
/>
</View>
)
}
ParentComponent over TaskInput
import React from 'react';
import { View } from 'react-native';
import styles from './styles';
import TaskInputContainer from '../task-input';
interface ITaskConfigurationProps {
title: string,
isInputForm?: boolean,
isRequired?: boolean,
}
const TaskConfiguration = (props: ITaskConfigurationProps) => {
return (
<View style={(props.isRequired) ? [styles.container, {backgroundColor: '#f25e5e'}] : styles.container}>
{ props.isInputForm && <TaskInputContainer title={props.title} /> }
</View>
);
}
export default TaskConfiguration;
const TaskScreen = (props: ITaskScreenProps) => {
return (
<View style={styles.container}>
<SectionTitle title={'Task Settings'} />
<ScrollView contentContainerStyle={styles.configurations}>
<TaskConfiguration title={"What you need to do?"} isInputForm={true} isRequired={true} />
<TaskConfiguration title={"Description"} isInputForm={true} />
<TaskConfiguration title={"Deadline"} />
<TaskConfiguration title={"Priority"} />
</ScrollView>
<Button isDone={true} navigation={props.navigation} />
</View>
)
}
TaskInput component takes one prop which is title and it will be in two places on my screen. One component will be called "Enter main task", another one is "Description". But this component will accept different states like currentMainTextInput and currentDescriptionTextInput. This is my idea of re-usable component TextInput, but I can't do what I want because if I set type in one input - other input will re-render with first input (both of them are one presentational component).
I want to use this dumb component in any place of my app. I don't want to create a new identical component and duplicate code, How can I do that? (P.S. I was thinking about "redux or class/hooks", but what should I use...)

invariant violaion.objects are not valid as react child issue in react-native

When I am trying to wrap redux form into the react-native elements it shows following error.
this is my code
import React,{ Component } from 'react';
import { Field,reduxForm } from 'redux-form';
import { Text,Input } from 'react-native-elements';
import { View,Button } from 'react-native';
const renderField=({label,keyboardType,name}) => {
return(
<View style={{flexDirection:'row',height:50,alignItems:'center' }}>
<Text>
{label}
</Text>
<Input />
</View>
)
}
const RegisterForm=props => {
const {handleSubmit}=props;
return(
<View style={{flex:1,flexDirection:'column',margin:40,justifyContent:'flex-start'}}>
<Field label="Username" component={renderField} name="username" />
<Button title='SUBMIT' onPress={handleSubmit} />
</View>
)
}
const Register=reduxForm({
form:'register',
})(RegisterForm);
export default Register;
When used FormInput in react-native elements it works then I am changed it into react-native elements 1.0.0beta4 and replace the formInput with Input component.
After that it shows above error.My debugger window also shows an error
debugger window
The error is due to your upgrade to react-native-elements beta which include breaking changes like the button component props :
The actual error is located in welcomePage.js file (as you can see in debugger), you need to change the object you pass to the button icon prop to a react component (see the button doc in the link above).

React-Native: Element type is invalid

I have problem with nativebase Footer
I have Container and if I include MyFooter, it give me this error:
Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in.
// main.js
import MyFooter from './MyFooter';
...
<Container>
<MyHeader title="Оплаты" />
<Content></Content>
<MyFooter />
</Container>
And Footer component
// MyFooter.js
const MyFooter = props => {
return (
<Footer>
<FooterTab>
<Button vertical active>
<Text>Info</Text>
</Button>
<Button vertical >
<Text>Remove</Text>
</Button>
</FooterTab>
</Footer>
);
}
export default MyFooter;
But if I change render method of MyFooter like this:
// MyFooter.js
return (
<View>
<Text>
Test
</Text>
</View>
)
So problem not in export/import, because with another render in MyFooter all work perfectly.
Can anybody help with this, please?
Answer - import { Text, Footer, FooterTab, Button, Icon } from 'react-native'; ('react-native' instead 'native-base')
Is this your MyFooter component try to export your component first export default MyFooter like these following:
const MyFooter = () => (
<Footer>
<FooterTab>
<Button vertical active>
<Icon name="information" />
<Text>Инфо</Text>
</Button>
<Button vertical >
<Icon name="add" />
<Text>Оплаты</Text>
</Button>
<Button vertical >
<Icon name="remove" />
<Text>Снятия</Text>
</Button>
</FooterTab>
</Footer>
);
export default MyFooter;
If you pasted your code exactly as is, then you're missing your closing brace after your return statement in MyFooter.js