i'm really new to react native and i encountered this error:
Components\MovieFocusCard.tsx: Assert fail
Failed building JavaScript bundle.
when trying to run the app.
i already tried removing & reinstalling node_modules but it didn't help.
i have no clue why this error is showing up and what the error message itself means. So any help is welcome!
Thanks in advance!
this is the error that shows up on the phone:
package.json:
{
"main": "node_modules/expo/AppEntry.js",
"scripts": {
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"web": "expo start --web",
"eject": "expo eject"
},
"dependencies": {
"#expo/vector-icons": "^10.0.0",
"babel-preset-react-native": "^4.0.0",
"expo": "^35.0.0",
"react": "16.8.3",
"react-dom": "16.8.3",
"react-native": "https://github.com/expo/react-native/archive/sdk-35.0.0.tar.gz",
"react-native-gesture-handler": "~1.3.0",
"react-native-reanimated": "~1.2.0",
"react-native-screens": "~1.0.0-alpha.23",
"react-native-paper": "^3.3.0",
"react-native-web": "^0.11.7",
"react-navigation": "^4.0.10",
"react-navigation-material-bottom-tabs": "^2.1.5",
"react-navigation-stack": "^1.10.3"
},
"devDependencies": {
"#types/react": "^16.9.14",
"#types/react-native": "^0.57.65",
"#types/react-navigation": "^3.4.0",
"babel-preset-expo": "^7.1.0",
"typescript": "^3.6.3"
},
"private": true
}
Below the code from the MovieFocusCard component:
import MovieDetails from "../Types/MovieDetails";
import { NavigationInjectedProps, withNavigation } from "react-navigation";
import React, { Component } from "react";
import { View, Text, Button, Image } from "react-native";
type MovieFocusCardProps = {};
type MovieFocusCardState = {
movieDetails: MovieDetails;
loaded: boolean;
};
class MovieFocusCard extends Component<
MovieFocusCardProps & NavigationInjectedProps,
MovieFocusCardState
> {
constructor(props: MovieFocusCardProps & NavigationInjectedProps) {
super(props);
this.state = {
movieDetails: null,
loaded: false
};
}
componentDidMount() {
this.GetMovieDetails(this.props.navigation.getParam("movieId", 0));
}
GetMovieDetails(id: number) {
let url: string = "https://api.themoviedb.org/3/movie/";
let apiKey: string = "?api_key=396734bc8915c8d1569cb4ff49b59c56";
fetch(url + id + apiKey)
.then(result => result.json())
.then(data =>
this.setState({
movieDetails: data,
loaded: true
})
)
.catch(console.log);
}
render() {
let posterUrl: string =
"https://image.tmdb.org/t/p/w200" + this.state.movieDetails.poster_path;
let rdate = new Date(
this.state.movieDetails.release_date
).toLocaleDateString();
let element;
this.state.loaded
? (element = (
<View>
<Text>{this.state.movieDetails.title}</Text>
<Image source={{ uri: posterUrl }} />
<Text>Release date: {rdate}</Text>
<Text>Summary: {this.state.movieDetails.overview}</Text>
<Text>Duration: {this.state.movieDetails.runtime} min</Text>
<Button
title="back"
onPress={() => {
this.props.navigation.goBack();
}}
>
Back
</Button>
</View>
))
: (element = <Text>Loading</Text>);
return { element };
}
}
export default withNavigation(MovieFocusCard);
//export default MovieFocusCard;
app.tsx code:
import React from "react";
import { createAppContainer } from "react-navigation";
import { createStackNavigator } from "react-navigation-stack";
import { createMaterialBottomTabNavigator } from "react-navigation-material-bottom-tabs";
import { Ionicons } from "#expo/vector-icons";
import MovieFocusCard from "./Components/MovieFocusCard";
import MovieHome from "./Components/MovieHome";
import HomeScreen from "./Components/HomeScreen";
const MovieHomeStack = createStackNavigator({
Movies: { screen: MovieHome },
MovieFocusCard: { screen: MovieFocusCard, params: { movieId: Number } }
});
const SerieHomeStack = createStackNavigator({});
const HomeStack = createStackNavigator({});
const MenuBarBottom = createAppContainer(
createMaterialBottomTabNavigator(
{
Movies: {
screen: MovieHomeStack,
navigationOptions: {
tabBarIcon: ({ tintColor }) => (
<Ionicons name="md-videocam" size={26} color={tintColor} />
)
}
},
Series: {
screen: SerieHomeStack,
navigationOptions: {
tabBarIcon: ({ tintColor }) => (
<Ionicons name="md-tv" size={26} color={tintColor} />
)
}
},
Home: {
screen: HomeStack,
navigationOptions: {
tabBarIcon: ({ tintColor }) => (
<Ionicons name="md-heart" size={26} color={tintColor} />
)
}
}
},
{
initialRouteName: "Home",
activeColor: "#000000",
inactiveColor: "#9e9e9e",
barStyle: { backgroundColor: "#ffffff" },
shifting: false //only shows label when clicked
}
)
);
export default MenuBarBottom;
Related
I am trying to connect my existing react-native project to GrapghQl using relay. __generated__ folder not creating AppQuery.graphql.js
Reference link.
error-
package.json
{
"name": "farmcom",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node node_modules/react-native/local-cli/cli.js start",
"relay": "relay-compiler --src ./src --schema ./schema.graphql",
"relayw": "relay-compiler --src ./src --schema ./schema.graphql --watch",
"test": "jest"
},
"dependencies": {
"graphql": "^14.0.2",
"prop-types": "^15.6.2",
"react": "16.5.0",
"react-native": "^0.57.2",
"react-native-collapsible": "^1.2.0",
"react-native-splash-screen": "^3.0.6",
"react-native-vector-icons": "^6.0.2",
"react-navigation": "^2.17.0",
"react-relay": "^1.7.0",
"relay": "^0.8.0-1"
},
"devDependencies": {
"babel-jest": "23.6.0",
"babel-plugin-relay": "^1.7.0",
"jest": "23.6.0",
"metro-react-native-babel-preset": "0.48.0",
"react-test-renderer": "16.5.0",
"relay-compiler": "^1.7.0",
"schedule": "^0.4.0"
},
"jest": {
"preset": "react-native"
}
}
.babelrc
{
"presets": ["module:metro-react-native-babel-preset"],
"plugins": ["relay"]
}
relay-environment.js
const { Environment, Network, RecordSource, Store } = require("relay-runtime");
const source = new RecordSource();
const store = new Store(source);
var myHeaders = new Headers();
// myHeaders.append('Access-Control-Allow-Headers', 'Content-Type');
// myHeaders.append("Content-Type", "multipart/form-data");
myHeaders.append("Content-Type", "application/json");
//'https://us-west-2.api.scaphold.io/graphql/narrow-pigs'
//'https://api.graph.cool/relay/v1/cj9z8yz7ig1zb0121dl0uwk2n
// Define a function that fetches the results of an operation (query/mutation/etc)
// and returns its results as a Promise:
function fetchQuery(operation, variables, cacheConfig, uploadables) {
return fetch("https://api.graph.cool/relay/v1/cjd4f6t7c35vn0159xw0lfij1", {
method: "POST",
headers: myHeaders,
mode: "cors",
body: JSON.stringify({
query: operation.text, // GraphQL text from input
variables
})
}).then(response => {
return response.json();
});
}
// Create a network layer from the fetch function
const network = Network.create(fetchQuery);
const environment = new Environment({
network,
store
});
export default environment;
App.js
import React, { Component } from "react";
import { StyleSheet, Text } from "react-native";
import SplashScreen from "react-native-splash-screen";
import { graphql, QueryRenderer } from "react-relay";
import ListAccount from "./src/listAccount";
import environment from "./src/relay.environment";
const AppQuery = graphql`
query AppQuery($count: Int!, $after: String) {
viewer {
...listAccount_viewer
}
}
`;
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
authentic: false
};
}
isAuthentic = authentic => {
this.setState({ authentic });
};
componentDidMount() {
SplashScreen.hide();
}
renderCard(item) {
return <Text>{item.text}</Text>;
}
render() {
return (
<QueryRenderer
environment={environment}
query={AppQuery}
variables={{
count: 1
}}
render={({ error, props }) => {
if (error) {
return <Text>{error.message}</Text>;
} else if (props) {
return (
<View>
<ListAccount viewer={props.viewer} />
</View>
);
}
return <Text>App Loading</Text>;
}}
/>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: "center"
}
});
listAccount.js
import React, { Component } from "react";
import {
Text,
View,
Button,
Checkbox,
TextInput,
TouchableOpacity
} from "react-native";
import { graphql, createPaginationContainer } from "react-relay";
import Account from "./account";
class ListAccount extends Component {
_loadMore() {
if (!this.props.relay.hasMore()) {
console.log(`Nothing more to load`);
return;
} else if (this.props.relay.isLoading()) {
console.log(`Request is already pending`);
return;
}
this.props.relay.loadMore(1);
}
render() {
return (
<View>
<Text>
{this.props.viewer.allAccounts.edges.map(({ node }, i) => (
<Account key={i} account={node} />
))}
</Text>
<Button onPress={() => this._loadMore()} title="more..." />
</View>
);
}
}
export default createPaginationContainer(
ListAccount,
{
viewer: graphql`
fragment listAccount_viewer on Viewer {
allAccounts(first: $count, after: $after, orderBy: createdAt_DESC)
#connection(key: "ListAccount_allAccounts") {
edges {
node {
...account_account
}
}
pageInfo {
hasNextPage
endCursor
}
}
}
`
},
{
direction: "forward",
query: graphql`
query listAccountForwardQuery($count: Int!, $after: String) {
viewer {
...listAccount_viewer
}
}
`,
getConnectionFromProps(props) {
return props.viewer && props.viewer.allAccounts;
},
getFragmentVariables(previousVariables, totalCount) {
return {
...previousVariables,
count: totalCount
};
},
getVariables(props, paginationInfo, fragmentVariables) {
return {
count: paginationInfo.count,
after: paginationInfo.cursor
};
}
}
);
account.js
import React, { Component } from "react";
import { Text } from "react-native";
import { graphql, createFragmentContainer } from "react-relay";
class Account extends Component {
render() {
return <Text>{this.props.account.acno}</Text>;
}
}
export default createFragmentContainer(
Account,
graphql`
fragment account_account on Account {
acno
}
`
);
I am trying to integrate redux with react-navigation using react-navigation-redux-helpers in react-native with expo. However, though I followed the documentations I get the following error.
This navigator has both navigation and container props, so it is unclear if it should own its own state. Remove props: "nav" if the navigator should get its state from the navigation prop. If the navigator should maintain its own state, do not pass a navigation prop.
Following is my code related to the redux and react-navigation implementation.
AppNavigator.js
import React from 'react';
import {createSwitchNavigator, createStackNavigator} from 'react-navigation';
import {connect} from 'react-redux';
import {reduxifyNavigator,createReactNavigationReduxMiddleware} from "react-navigation-redux-helpers";
import MainTabNavigator from './MainTabNavigator';
export const AuthStack = createStackNavigator(
{
Main: MainTabNavigator,
},
{
headerMode: 'none'
}
);
export const AppNavigator = createSwitchNavigator(
{
Auth: AuthStack,
},
{
headerMode: 'none',
initialRouteName: 'Auth',
}
);
export const NavMiddleware = createReactNavigationReduxMiddleware(
"root",
state => state.nav,
);
const addListener = reduxifyNavigator(AppNavigator, 'root');
const mapStateToProps = state => ({
nav: state.nav,
});
export const AppWithNavigationState = connect(mapStateToProps)(addListener);
App.js
import React from 'react';
import {Platform, StatusBar, StyleSheet, View} from 'react-native';
import {AppLoading, Asset, Font, Icon} from 'expo';
import {AppWithNavigationState} from './navigation/AppNavigator';
import {applyMiddleware, createStore} from "redux";
import AppReducer from './reducers/AppReducer'
import {Provider} from "react-redux";
import {NavMiddleware} from './navigation/AppNavigator'
const store = createStore(AppReducer,applyMiddleware(NavMiddleware));
export default class App extends React.Component {
state = {
isLoadingComplete: false,
};
render() {
if (!this.state.isLoadingComplete && !this.props.skipLoadingScreen) {
return (
<AppLoading
startAsync={this._loadResourcesAsync}
onError={this._handleLoadingError}
onFinish={this._handleFinishLoading}
/>
);
} else {
return (
<View style={styles.container}>
{Platform.OS === 'ios' && <StatusBar barStyle="default" />}
<Provider store={store}>
<AppWithNavigationState/>
</Provider>
</View>
);
}
}
_loadResourcesAsync = async () => {
return Promise.all([
Asset.loadAsync([
require('./assets/images/robot-dev.png'),
require('./assets/images/robot-prod.png'),
]),
Font.loadAsync({
// This is the font that we are using for our tab bar
...Icon.Ionicons.font,
// We include SpaceMono because we use it in HomeScreen.js. Feel free
// to remove this if you are not using it in your app
'space-mono': require('./assets/fonts/SpaceMono-Regular.ttf'),
}),
]);
};
_handleLoadingError = error => {
// In this case, you might want to report the error to your error
// reporting service, for example Sentry
console.warn(error);
};
_handleFinishLoading = () => {
this.setState({ isLoadingComplete: true });
};
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
},
});
navReducer.js
import {AppNavigator} from '../navigation/AppNavigator';
const router = AppNavigator.router;
const mainNavAction = router.getActionForPathAndParams('Auth');
const initialNavState = router.getStateForAction(mainNavAction);
const NavigationReducer = (state = initialNavState, action) => {
console.log('routes', router);
return router.getStateForAction(action, state) || state;
};
export default NavigationReducer;
AppReducer.js
"use strict";
import {VendorReducer} from './vendorReducer';
import {combineReducers} from "redux";
import NavigationReducer from "./navReducer";
const AppReducer = combineReducers({
nav:NavigationReducer,
vendor: VendorReducer,
});
export default AppReducer;
Following is my package.json.
{
"name": "my-new-project",
"main": "node_modules/expo/AppEntry.js",
"private": true,
"scripts": {
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"eject": "expo eject",
"test": "node ./node_modules/jest/bin/jest.js --watchAll"
},
"jest": {
"preset": "jest-expo"
},
"dependencies": {
"#expo/samples": "2.1.1",
"expo": "^30.0.1",
"react": "16.3.1",
"react-native": "https://github.com/expo/react-native/archive/sdk-30.0.0.tar.gz",
"react-navigation": "2.16.0",
"react-navigation-redux-helpers": "2.0.6",
"react-redux": "5.0.7",
"redux": "4.0.0",
"redux-logger": "3.0.6",
"redux-thunk": "2.3.0"
},
"devDependencies": {
"jest-expo": "30.0.0",
"redux-devtools": "3.4.1"
}
}
I hope someone could help me to get through this. Thanks in-advance.
This was also my mistake! solved it by:
const mapStateToProps = state => ({
state: state.nav,
});
pay attention to state: state.nav.
If you need, i can post my whole redux integration with the navigation that work for me.
I got this issue today morning when I was trying to implement a Fluid Navigation between scenes using react-native-fluid-transitions. After I replace createStackNavigator for createFluidNavigator or FluidNavigator I got the screen issue below:
Invariant Violation: withNavigation can only be used on a view hierarchy of a navigator. The wrapped component is unable to get access to navigation from props or context.
Here are my files
index.js
import React from 'react';
import { Platform } from 'react-native';
import {
SafeAreaView,
createStackNavigator,
} from 'react-navigation';
import screens from '../screens';
import AppDrawer, {
contentOptions as appDrawerContentOptions,
} from '../components/AppDrawer';
import { createFluidNavigator, FluidNavigator } from 'react-navigation-fluid-transitions';
// We already have a status bar from expo
if (Platform.OS === 'android') {
SafeAreaView.setStatusBarHeight(0);
}
const defaultStack = createFluidNavigator (
{
Home: {
screen: screens.CpfCheckScreen
},
Login: {
screen: screens.LoginScreen
},
SelectAssociate: {
screen: screens.SelectAssociateScreen
},
EmailRegister: {
screen: screens.EmailRegisterScreen
},
AssociateSelected: {
screen: screens.AssociatedSelectedScreen
},
Welcome: {
screen: screens.WelcomeScreen
},
Survey: {
screen: screens.SurveyScreen
},
WaitingIndication: {
screen: screens.WaitingIndicationScreen
},
BindingSuccess: {
screen: screens.BindingSuccessScreen
},
AuthenticationSteps: {
screen: screens.AuthenticationStepsScreen
},
ProcessingData: {
screen: screens.ProcessingDataScreen
},
SignaturePicture: {
screen: screens.SignaturePictureScreen
},
// CpfPicture: {
// screen: screens.CpfPictureScreen
// },
ConfirmData: {
screen: screens.ConfirmDataScreen
},
DataValidation: {
screen: screens.DataValidationScreen
},
MembershipTerms: {
screen: screens.MembershipTermsScreen
},
SuccessfullRegistration: {
screen: screens.SuccessfullRegistrationScreen
},
ApprovedRegistration: {
screen: screens.ApprovedRegistrationScreen
},
FailedRegistration: {
screen: screens.FailedRegistrationScreen
},
SecurityQuestion:
{
screen: screens.SecurityQuestionScreen
},
AssociatedLoginScreen: {
screen: screens.AssociatedLoginScreen
},
NewAssociateQuizScreen: {
screen: screens.NewAssociateQuizScreen
},
NewAssociateSuccessScreen: {
screen: screens.NewAssociateSuccessScreen
}
},
{
initialRouteName: 'AssociatedLoginScreen',
headerMode: 'none',
}
)
export default defaultStack;
screens.js
import InitializeScreen from './InitializeScreen';
import LoginScreen from './LoginScreen';
import EmailRegisterScreen from './EmailRegisterScreen';
import CpfCheckScreen from './CpfCheckScreen'
import SelectAssociateScreen from './SelectAssociateScreen'
import AssociatedSelectedScreen from './AssociatedSelectedScreen'
import WelcomeScreen from './WelcomeScreen'
import SurveyScreen from './SurveyScreen'
import WaitingIndicationScreen from './WaitingIndicationScreen'
import BindingSuccessScreen from './BindingSuccessScreen'
import AuthenticationStepsScreen from './AuthenticationStepsScreen'
import SignaturePictureScreen from './SignaturePictureScreen'
import ConfirmDataScreen from './ConfirmDataScreen'
// import RgPictureScreen from './RgPictureScreen'
// import CpfPictureScreen from './CpfPictureScreen'
import ProcessingDataScreen from './ProcessingDataScreen'
import DataValidationScreen from './DataValidationScreen'
import MembershipTermsScreen from './MembershipTermsScreen'
import SuccessfullRegistrationScreen from './SuccessfullRegistrationScreen'
import ApprovedRegistrationScreen from './ApprovedRegistrationScreen'
import FailedRegistrationScreen from './FailedRegistrationScreen'
import SecurityQuestionScreen from './SecurityQuestionScreen'
import AssociatedLoginScreen from './AssociatedLoginScreen'
import NewAssociateQuizScreen from './NewAssociateQuizScreen'
import NewAssociateSuccessScreen from './NewAssociateSuccessScreen'
/*
import ModalScreen from './ModalScreen';
import DetailsRegisterScreen from './DetailsRegisterScreen';
import DashboardScreen from './DashboardScreen';
import TaskDetailsScreen from './TaskDetailsScreen';
import TasksScreen from './TasksScreen';
import EventScreen from './EventScreen';
import TaskStepsScreen from './TaskStepsScreen';
import QRScanScreen from './QRScanScreen';
import TaskSuccessScreen from './TaskSuccessScreen';
import LogoutScreen from './LogoutScreen';
import ProductScreen from './ProductScreen';
import ProductQRScanScreen from './ProductQRScanScreen';
import ProductSuccessScreen from './ProductSuccessScreen';
import ContinueAsScreen from './ContinueAsScreen';
import UserProfileScreen from './UserProfileScreen';
import SocialPageLikeTaskScreen from './SocialPageLikeTaskScreen';
*/
export default {
InitializeScreen,
LoginScreen,
EmailRegisterScreen,
CpfCheckScreen,
SelectAssociateScreen,
AssociatedSelectedScreen,
WelcomeScreen,
SurveyScreen,
WaitingIndicationScreen,
BindingSuccessScreen,
AuthenticationStepsScreen,
SignaturePictureScreen,
// RgPictureScreen,
// CpfPictureScreen,
ConfirmDataScreen,
ProcessingDataScreen,
DataValidationScreen,
MembershipTermsScreen,
SuccessfullRegistrationScreen,
ApprovedRegistrationScreen,
FailedRegistrationScreen,
SecurityQuestionScreen,
AssociatedLoginScreen,
NewAssociateQuizScreen,
NewAssociateSuccessScreen
/*
ModalScreen,
DetailsRegisterScreen,
DashboardScreen,
TaskDetailsScreen,
TasksScreen,
EventScreen,
TaskStepsScreen,
QRScanScreen,
TaskSuccessScreen,
LogoutScreen,
ProductScreen,
ProductQRScanScreen,
ProductSuccessScreen,
ContinueAsScreen,
UserProfileScreen,
SocialPageLikeTaskScreen,*/
};
NewAssociateQuizForm
import React from 'react';
import { StyleSheet, View } from 'react-native';
import { Text } from 'native-base';
import { withFormik } from 'formik';
import { withNavigation } from 'react-navigation';
import yup from 'yup';
import { withApollo } from 'react-apollo';
import Auth from '../lib/auth';
import Button from './Button';
import colors from '../config/colors';
import { moderateScale } from '../config/scaling';
import { Transition } from 'react-navigation-fluid-transitions'
import Carousel, { Pagination } from 'react-native-snap-carousel';
import FormField from './FormField';
import ItemInput from './ItemInput';
import AlertContainer from './AlertContainer';
const enhancer = withFormik({
validationSchema: yup.object().shape({
name: yup
.string()
.required('Este campo é obrigatório'),
}),
mapPropsToValues: props => ({
associate: '',
}),
handleSubmit: (values, { props: { client, navigation }, setSubmitting }) => {
const { associate } = values;
console.log('handling submit')
if (!associate ) {
AlertContainer.show({
message: 'Sócio inexistente',
buttonText: 'Tentar novamente',
});
setSubmitting(false);
return;
}
Auth.loginRequest(associate)
.then(res => {
if (!res || !res.data || !res.data.token) {
// We can't tell much to the user
console.log('not working')
AlertContainer.show({
message: 'Erro interno',
buttonText: 'Tentar novamente',
});
return;
}
const { token } = res.data;
console.log('working')
Auth.login(token, client).then(() => navigation.navigate('App'));
})
.catch(error => {
console.log('error on login request', error);
const { response } = error;
if (response) {
// HTTP Request response
const { status } = response;
let message = 'Erro interno';
if (status === 400) {
message = 'Dados inválidos';
}
if (status === 401) {
message = 'Sócio inválido';
}
AlertContainer.show({
message,
buttonText: 'Tentar novamente',
});
} else {
// Raw error message
const errorString = error.toString();
if (errorString && errorString.indexOf('Network Error') >= 0) {
AlertContainer.show({
message: 'Erro de conexão',
buttonText: 'Tentar novamente',
});
}
}
})
.finally(() => setSubmitting(false));
},
});
const AssociateForm = props => {
const {
values,
touched,
errors,
handleSubmit,
setFieldValue,
setFieldTouched,
navigation,
isSubmitting,
} = props;
const renderItem = () => {
return (
<FormField
validateStatus={getValidateStatus('associate')}
error={getError('associate')}
>
<ItemInput
placeholder="Nome e sobrenome..."
onChangeText={text => {
setFieldValue('associate', text)
}}
onBlur={() => setFieldTouched('associate')}
initialValue={values.associate}
maxLength={32}
/>
</FormField>
)
}
const pagination = () => {
return (
<Pagination
dotsLength={3}
activeDotIndex={0}
containerStyle={{ backgroundColor: 'transparent' }}
dotStyle={{
width: 10,
height: 10,
borderRadius: 5,
marginHorizontal: 8,
backgroundColor: '#a18037'
}}
inactiveDotStyle={{
// Define styles for inactive dots here
}}
inactiveDotOpacity={0.4}
inactiveDotScale={0.6}
/>
);
}
const getValidateStatus = param => {
return errors[param] && touched[param]
? 'error'
: touched[param]
? 'success'
: '';
};
const getError = param => {
return errors[param] && touched[param] ? errors[param] : '';
};
return (
<View style={styles.container}>
<Text style={styles.title}>
Responda o questionário
</Text>
<Text style={styles.subtitle}>
{`Para ser um sócio Fiduc você precisa responder a este questionário e entraremos em contato para uma entrevista`}
</Text>
<View>
{ renderItem() }
{ pagination() }
</View>
<Button
primary
style={styles.submitButton}
onPress={ () => { navigation.navigate('NewAssociateSuccessScreen') }}
disabled={isSubmitting}
loading={isSubmitting}
>
<Text
style={[
styles.submitButtonText,
isSubmitting && { color: colors.secondary_text },
]}
uppercase={false}
>
Receber Indicação
</Text>
</Button>
</View>
);
};
export default withNavigation(withApollo(enhancer(AssociateForm)));
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'column',
justifyContent: 'center',
},
submitButton: {
height: moderateScale(20),
borderRadius: 0,
justifyContent: 'center',
marginTop: moderateScale(50),
paddingHorizontal: 48,
alignSelf: 'center',
},
submitButtonText: {
color: colors.button_text,
fontSize: moderateScale(18),
textAlign: 'center',
alignSelf: 'center',
},
whiteText: {
color: colors.secondary_text,
},
title: {
color: colors.text,
fontSize: moderateScale(23),
textAlign: 'center',
marginBottom: 8
},
subtitle: {
color: colors.text,
fontSize: moderateScale(12),
textAlign: 'justify',
marginBottom: 30
},
description: {
color: colors.secondary_text,
fontSize: moderateScale(16),
textAlign: 'center',
paddingVertical: moderateScale(10),
},
wrapper: {
}
});
package.json
{
"name": "fidelidade-app",
"version": "0.1.0",
"private": true,
"devDependencies": {
"babel-eslint": "^8.2.3",
"eslint": "^4.19.1",
"eslint-config-react-app": "^2.1.0",
"eslint-config-universe": "git+https://git#github.com/expo/eslint-config-universe",
"eslint-plugin-babel": "^5.1.0",
"eslint-plugin-flowtype": "^2.46.3",
"eslint-plugin-import": "^2.11.0",
"eslint-plugin-react": "^7.8.2",
"jest-expo": "26.0.0",
"prettier": "^1.12.1",
"react-native-scripts": "1.13.2",
"react-test-renderer": "16.3.0-alpha.1"
},
"main": "./node_modules/react-native-scripts/build/bin/crna-entry.js",
"scripts": {
"start": "react-native-scripts start",
"eject": "react-native-scripts eject",
"android": "react-native-scripts android",
"ios": "react-native-scripts ios",
"test": "jest",
"postinstall": "patch -p0 < apollo.patch || true",
"lint": "eslint ."
},
"jest": {
"preset": "jest-expo"
},
"dependencies": {
"apollo-boost": "^0.1.4",
"axios": "^0.18.0",
"expo": "^27.0.0",
"formik": "^0.11.11",
"graphql": "^0.13.2",
"graphql-tag": "^2.9.1",
"moment-timezone": "^0.5.17",
"native-base": "^2.4.2",
"react": "16.3.1",
"react-apollo": "^2.1.3",
"react-native": "https://github.com/expo/react-native/archive/sdk-27.0.0.tar.gz",
"react-native-datepicker": "^1.7.2",
"react-native-easy-grid": "^0.1.17",
"react-native-gesture-password": "^0.3.4",
"react-native-maps-directions": "^1.6.0",
"react-native-masked-text": "^1.7.2",
"react-native-modal": "^6.1.0",
"react-native-scrollable-tab-view": "^0.8.0",
"react-native-snap-carousel": "^3.7.3",
"react-native-svg": "^6.5.2",
"react-native-swiper": "^1.5.13",
"react-navigation": "^2.0.1",
"react-navigation-fluid-transitions": "^0.2.6",
"yup": "^0.24.1"
}
}
I'm developing a new app with RN and using TabNavigator from react-navigation library, the most basic example of TabNavigator only showing first Tab. I've read somewhere that it could be a bug and could be solved by downgrading react-navigation to 1.0.3 but it didn't work for me. How to solve it?
tab1
tab2
app.js
import React, { Component } from 'react';
import Dashboard from './screens/Dashboard';
import Profile from './screens/Profile';
// import {I18nManager} from 'react-native';
// import { Container, Header, Content, Footer, FooterTab, Button, Icon, Text, Badge, Tab, Tabs } from 'native-base';
import { TabNavigator, TabBarBottom } from 'react-navigation';
import Ionicons from 'react-native-vector-icons/Ionicons';
export default TabNavigator({
home: { screen: Dashboard },
profile: { screen: Profile },
nav: { screen: Dashboard },
},
{
navigationOptions: ({ navigation }) => ({
tabBarIcon: ({ focused, tintColor }) => {
const { routeName } = navigation.state;
let iconName;
if (routeName === 'home') {
iconName = `ios-pulse${focused ? '' : '-outline'}`;
} else if (routeName === 'profile') {
iconName = `ios-person${focused ? '' : '-outline'}`;
}
// You can return any component that you like here! We usually use an
// icon component from react-native-vector-icons
return <Ionicons name={iconName} size={25} color={tintColor} />;
},
}),
tabBarOptions: {
activeTintColor: 'blue',
inactiveTintColor: 'gray',
},
tabBarComponent: TabBarBottom,
lazy: false,
tabBarPosition: 'bottom',
animationEnabled: false,
swipeEnabled: false,
}
);
Dashboard.js
import React, { Component } from 'react';
import { TouchableOpacity,
Title,
Subtitle,
Tile,
Divider,
ImageBackground,
Card,
Image,
View,
Caption,
GridRow,
ListView,
Screen
} from '#shoutem/ui';
// import I18n from 'react-native-i18n';
// import {I18nManager} from 'react-native';
// I18nManager.forceRTL(true);
export default class Dashboard extends Component {
constructor(props) {
super(props);
this.renderRow = this.renderRow.bind(this);
this.state = {
restaurants: [
{
'name': 'برنامه ۳۰ روزه هوازی',
'address': 'چربی سوزی | کاهش وزن',
'image': { 'url': 'https://shoutem.github.io/static/getting-started/restaurant-1.jpg' },
},
{
'name': 'تمرین سینه',
'address': 'افزایش قدرت و حجم عضلات سینه و فرم دهی به آن',
'image': { 'url': 'https://shoutem.github.io/static/getting-started/restaurant-2.jpg' },
},
{
'name': 'تمرین شکم',
'address': 'حاضرید که عضلات شکمتان را ورزیده و تکه کنید؟ حرکاتی که در زیر آمده، راهنمایی است که همیشه برای شما کافی و مفید خواهد بود.',
'image': { 'url': 'https://shoutem.github.io/static/getting-started/restaurant-3.jpg' },
},
{
'name': 'تمرین سینه',
'address': 'افزایش قدرت و حجم عضلات سینه و فرم دهی به آن',
'image': { 'url': 'https://shoutem.github.io/static/getting-started/restaurant-2.jpg' },
},
{
'name': 'تمرین شکم',
'address': 'حاضرید که عضلات شکمتان را ورزیده و تکه کنید؟ حرکاتی که در زیر آمده، راهنمایی است که همیشه برای شما کافی و مفید خواهد بود.',
'image': { 'url': 'https://shoutem.github.io/static/getting-started/restaurant-3.jpg' },
},
{
'name': 'تمرین ران پا',
'address': 'این یک تست است.',
'image': { 'url': 'https://shoutem.github.io/static/getting-started/restaurant-2.jpg' },
},
],
};
}
renderRow(rowData, sectionId, index) {
// rowData contains grouped data for one row,
// so we need to remap it into cells and pass to GridRow
if (index === '0') {
return (
<TouchableOpacity key={index}>
<ImageBackground
styleName="large"
source={{ uri: rowData[0].image.url }}
>
<Tile>
<Title styleName="md-gutter-bottom">{rowData[0].name}</Title>
<Subtitle styleName="sm-gutter-horizontal">{rowData[0].address}</Subtitle>
</Tile>
</ImageBackground>
<Divider styleName="line" />
</TouchableOpacity>
);
}
const cellViews = rowData.map((restaurant, id) => {
return (
<TouchableOpacity key={id} styleName="flexible">
<Card styleName="flexible">
<Image
styleName="medium-wide"
source={{ uri: restaurant.image.url }}
/>
<View styleName="content">
<Subtitle numberOfLines={3}>{restaurant.name}</Subtitle>
<View styleName="horizontal">
<Caption styleName="collapsible" numberOfLines={2}>{restaurant.address}</Caption>
</View>
</View>
</Card>
</TouchableOpacity>
);
});
return (
<GridRow columns={2}>
{cellViews}
</GridRow>
);
}
render() {
const restaurants = this.state.restaurants;
// Group the restaurants into rows with 2 columns, except for the
// first restaurant. The first restaurant is treated as a featured restaurant
let isFirstArticle = true;
const groupedData = GridRow.groupByRows(restaurants, 2, () => {
if (isFirstArticle) {
isFirstArticle = false;
return 2;
}
return 1;
});
return (
<ListView
data={groupedData}
renderRow={this.renderRow}
/>
);
}
}
Profile.js
import React, { Component } from 'react';
import { Container, Header, Content, Form, Item, Input, Label } from 'native-base';
// import I18n from 'react-native-i18n';
// import {I18nManager} from 'react-native';
// I18nManager.forceRTL(true);
export default class Profile extends Component {
render() {
return (
<Container>
<Header />
<Content>
<Form>
<Item floatingLabel>
<Label>نام</Label>
<Input />
</Item>
<Item floatingLabel last>
<Label>قد (سانتیمتر)</Label>
<Input />
</Item>
</Form>
</Content>
</Container>
);
}
}
package.json
"dependencies": {
"#shoutem/ui": "^0.23.4",
"native-base": "^2.4.2",
"react": "16.3.1",
"react-native": "0.55.3",
"react-native-vector-icons": "^4.6.0",
"react-navigation": "^1.0.3"
},
"devDependencies": {
"babel-jest": "22.4.3",
"babel-preset-react-native": "4.0.0",
"eslint": "^4.19.1",
"eslint-plugin-react": "^7.7.0",
"jest": "22.4.3",
"react-test-renderer": "16.3.1"
},
"jest": {
"preset": "react-native"
}
I've already tried latest version of react-navigation so its downgraded version you see in package.json
I've found solution to this, and I'm going to be as specific as I can for all the people out there that might face this!
First of all it's a problem with I18nManager.forceRTL(true);
the moment you use this line of code anywhere on your react-native code that its screen gonna get rendered, and on 2nd reload, the app the layout is being change to RTL, and it does not change even if you comment that line! You'll have to use I18nManager.forceRTL(false); and reload a couple of times to get back to normal ltr setup.
The thing is... some of us really need that RTL layout change like I thought I did! Well guess what react-navigation does not respect that, at least for now and in the TabNabigator dept.
So to sum it all up: RTL layout on RN will break your react-navigation's Tab Navigation! (as of the current version you can see in the packages.json above) The issue makes only the first that visible and for the others a bland tab shows, if you turn on the animation or swipe other tabs will show but tabs behave in a weird way, meaning the last tab is active when the first one is active and vice versa... middle tabs are never focused by the way.
So you should know you can't use tabbed navigation with RTL layout. I'll update this answer after this issue got a fix!
I have run it using react-native run-ios, and all the tabs display a different screen. If you are referring to the fact that the nav tab does not change when you click on it whilst on the home tab, both the home and nav tabs are using the Dashboard screen.
The following is my package.json file for this project:
{
"name": "a",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node node_modules/react-native/local-cli/cli.js start",
"test": "jest"
},
"dependencies": {
"react-native-code-push": "1.15.0-beta",
"#babel/core": "^7.0.0-beta.40",
"#shoutem/ui": "^0.23.4",
"eslint": "^3.19.0",
"native-base": "^2.4.2",
"react": "16.3.1",
"react-native": "0.55.3",
"react-native-vector-icons": "^4.6.0",
"react-navigation": "^1.5.11"
},
"devDependencies": {
"babel-jest": "22.4.3",
"babel-preset-react-native": "4.0.0",
"jest": "22.4.3",
"react-test-renderer": "16.3.1"
},
"jest": {
"preset": "react-native"
}
}
I want to change an icon of TabBarIOS and wrote the following codes, but become the error of Element type is invalid.
import React from 'react';
import { View, TabBarIOS } from 'react-native';
import Icon from 'react-native-vector-icons/Ionicons';
import CommunicationTab from './components/communication_tab';
import WhereaboutsTab from './components/whereabouts_tab';
export default class App extends React.Component {
constructor() {
super();
this.state = {
selectedTab: 'WhereaboutsTab',
};
}
render() {
return (
<TabBarIOS selectedTab={this.state.selectedTab}>
<Icon.TabBarItem
title="whereabouts"
iconName='ios-home-outline'
selectedIconName='ios-home'
selected={this.state.selectedTab === 'WhereaboutsTab'}
onPress={() => {
this.setState({
selectedTab: 'WhereaboutsTab'
});
}}
>
<WhereaboutsTab />
</Icon.TabBarItem>
<Icon.TabBarItem
title="communication"
iconName='ios-settings-outline'
selectedIconName='ios-settings'
selected={this.state.selectedTab === 'CommunicationTab'}
onPress={() => {
this.setState({
selectedTab: 'CommunicationTab'
});
}}
>
<CommunicationTab />
</Icon.TabBarItem>
</TabBarIOS>
);
}
}
When use following codes, do not have any problem.
<Icon name="ios-home" />
It is a project of expo which I made in create-react-native-app, will this be related?
package.json
"dependencies": {
"expo": "^16.0.0",
"moment": "^2.18.1",
"react": "16.0.0-alpha.6",
"react-native": "^0.43.4",
"react-native-action-button": "^2.6.9",
"react-native-md-textinput": "^2.0.4",
"react-native-modal-datetime-picker": "^4.6.0",
"react-native-swipeout": "^2.1.1",
"react-native-vector-icons": "^4.1.1"
}
I think you have a typo there.
Try replacing Icon.TabBarItem to Icon.TabBarItemIOS instead.