React Native | Passing data between components - react-native

I am a beginner with React Native. I would like to pass data between two components. I get the following error:
TypeError: undefined is not an object (evaluating 'params.title'
App.js
import React from 'react';
import TabBar from './components/TabBar';
export default function App() {
return (
<TabBar title="Hall Building"/>
);
}
TabBar.js
import React, { useState } from 'react';
import { Text } from 'react-native';
export default function TabBar({ params }){
const [tabContent] = useState([
{
title: params.title,
}
])
return(
<Text>
{ tabContent.title }
</Text>
);
}
export { TabBar };

There are a couple things you're doing wrong in your TabBar component.
In theTabBar you are destructuring the property params but your property is called title. You either have to remove the curly braces or rename it to title. If you rename params to title you can remove params. and simply leave title. If you chose to remove the curly braces you can leave it as it is.
Then you also try to access tabContent.title but tabContent is an array with objects. You either have to remove the square brackets and pass an object as argument to useState OR you can access the title by getting the first index like so tabContent[0].title.

Change your TabBar into this :
import React, { useState } from 'react';
import { Text } from 'react-native';
export default function TabBar({ title }){
const [tabContent] = useState(title)
return(
<Text>
{ tabContent }
</Text>
);
}
export { TabBar };
hope it helps.

Related

How can I pass params through react-navigation module without navigate to other page?

I am using react-navigation module to implement the bottom tab bar, and now I want to pass the parameters to page B during the operation in page A without page jumping, is there any way to achieve this?
I read the official documentation of react-navigation, and it seems that only the navigation.navigation method can pass parameters across pages, but this will cause page jumps
You can use the AsyncStorage package. Save the data you will use on PageB with a key on PageA. Then get saved data on the PageB.
import React, { useEffect } from 'react';
import { Button } from 'react-native';
import AsyncStorage from '#react-native-async-storage/async-storage';
export default PageA = ({ navigation }) => {
useEffect(() => {
AsyncStorage.setItem("PageParams", "something")
}, [])
return (
<Button title='Navigate' onPress={() => navigation.navigate("PageB")} />
);
};
import { View } from 'react-native';
import React, { useEffect } from 'react';
import AsyncStorage from '#react-native-async-storage/async-storage';
export default PageB = () => {
useEffect(async () => {
const params = await AsyncStorage.getItem("PageParams")
console.log(params) // output: something
})
return (
<View />
);
};

How to fix an Objects are not valid as a React child Error?

I am very new to programming with React-native, and I was wondering if anyone could explain how I should fix this error? I was following along with a tutorial and had an error come up due to this section of code, even though it matched the tutorial code.
Here is the section of code:
import React, { createContext, useContext } from "react";
import * as Google from "expo-google-app-auth";
const AuthContext = createContext({});
export const AuthProvider = ({ children }) => {
const signInWithGoogle = async() => {
await Google.logInAsync
}
return (
<AuthContext.Provider
value={{
user: null,
}}
>
{children}
</AuthContext.Provider>
);
};
export default function useAuth() {
return useContext(AuthContext);
}
These other two sections may be relevant as well:
Root of the App:
import React from 'react';
import { Text, View, SafeAreaView, Button, Alert } from 'react-native';
import AuthProvider from "./hooks/useAuth";
import StackNavigator from "./StackNavigator";
import { NavigationContainer} from "#react-navigation/native";
// Function for creating button
export default function App() {
return (
<NavigationContainer>
<AuthProvider>
<StackNavigator />
</AuthProvider>
</NavigationContainer>
);
}
This is my code for the Login Screen:
import React from 'react';
import { View, Text } from 'react-native';
import useAuth from '../hooks/useAuth';
const LoginScreen = () => {
const { user } = useAuth();
console.log(user);
return (
<View>
<Text>
Login to the app
</Text>
</View>
);
};
export default LoginScreen
This is the error that appears:
Error: Objects are not valid as a React child (found: object with keys {}). If you meant to render a collection of children, use an array instead.
I suggest you auth with firebase. it makes easier this things.

Context API w/ React Navigation (React Native)

I'm trying to wrap my mind around using Context in my React Native app that uses React Navigation. I think I am way off on this one. I am simply trying to pass the name of a book to my entire app through the navigation stacks.
App.js
const BookContext = React.createContext();
class BookProvider extends Component {
state = {
name: 'book name'
}
render() {
return (
<BookContext.Provider value={{
name: this.state.name
}}>
{this.props.children}
</BookContext.Provider>
)
}
}
export default function App() {
return (
<BookProvider>
<BookContext.Consumer>
{({ name }) => (<Routes name={name} />)} //my react navigation stacks component
</BookContext.Consumer>
</BookProvider>
);
}
and in Book.js (a component in the navigation stack)
componentDidMount() {
console.log(this.context)
}
returns an empty object {}
Any help is appreciated!
To save you some Googling, this is the correct approach: https://github.com/react-navigation/react-navigation/issues/935#issuecomment-359675855
Another way, if you're using a relatively new version of React, and your component in question at that route is a functional component, is to use the useContext React hook.
e.g.
import React, { useContext } from 'react'
import { BookContext } from '/path/to/BookContext'
function BookConsumerComponent() {
const { name } = useContext(BookContext);
console.log(name);
}

Module not found - while adding a component in app.js

I am using React Native. Below is my code in app.js.
import React, { useState } from 'react';
import { StyleSheet, Text, View } from 'react-native';
import Header from './components/Header';
export default function App() {
return (
<View>
</View>
);
}
I made another directory in root and added another js file which is Header.js. It contains below code.
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
export default function Header() {
return (
<View>
</View>
);
}
I got an error message below.
The development server returned response error code: 500
The module ./components/Header could not be found
Directory Structure
Please let me know if you need more info.
It should be
const Header = () => {
return (
<View>
</View>
);
}
export default Header
Don't just reload an app, restart packager also.
Please correct your functional header component as:
const Header = () => {
return(
<View>.............</View>
)}
export default Header
And run react-native start and react-native run-android
Replace Header component to this:-
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
const Header = ({props}) => { // you can also access props like this
return (
<View>
</View>
);
}

MobX with React Native: store is undefined

This is my first go at using MobX so this may be a simpler problem than I imagine, but I'm not getting any errors with the things I've tried; the store is simply undefined wherever I try to use it. I've tried both importing the store directly into components and passing props from the main file (also with , but I'm not sure if I used that right). I've experimented with several different .babelrc file settings as well, but that doesn't seem to be an issue.
Here is the UserStore:
import React from 'react';
import { observable } from 'mobx';
class UserStore {
#observable info = {
username: "bob",
password: "secret",
email: "bob#email.com"
}
}
const userStore = new UserStore()
export default userStore;
Here is a simplified App.js:
import React, { Component } from 'react';
import { StyleSheet, Text, View } from 'react-native';
import Profile from './app/Profile.js';
import { UserStore } from './app/UserStore.js';
export default class App extends Component {
constructor(){
super();
this.state = {
page: 'Profile',
}
}
changePage(){
switch (this.state.page) {
case "Profile":
return <Profile logout={this.logout.bind(this)} userStore={UserStore}/>;
}
}
render() {
return (
<View>
{this.changePage()}
</View>
);
}
}
And here is a simplified Profile.js:
import React, { Component } from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
import { observer } from 'mobx-react/native';
#observer
export default class Profile extends Component {
render() {
console.log(this.props.userStore);
return (
<View>
<Text>Profile Page</Text>
<Text>username: {props from store go here}</Text>
<Text>password: {props from store go here}</Text>
<Text>email: {props from store go here}</Text>
</View>
);
}
}
All I'm trying to do right now is get the pre-defined observable "info" object from the store to the Profile.js component and display that information. This is being way more difficult than it should be - any insight is greatly appreciated!
Since you declared export default userStore; in UserStore.js
Try changing the way you import in App.js by removing the {}:
import UserStore from './app/UserStore.js';
{} is needed only if you want to do a named import. Here is a good read if you want to know more.