Passing aprop from a page to another in react native

component Message

import { View, Text } from 'react-native'
import React from 'react'

export default function Message({name,feed}) {
	return (
		<View>
			<Text>{name}</Text>
			<Text>{feed.id}</Text>

		</View>
	)
}

//Home Page

import { StyleSheet, Dimensions, Text, View, TextInput, ActivityIndicator, FlatList, Button, StatusBar, TouchableOpacity } from 'react-native';
import React, {useEffect, useState} from 'react';
import { Video, AVPlaybackStatus } from 'expo-av';
//play button icon
import {Ionicons } from '@expo/vector-icons';
import Message from '../components/Message';

const Home = () => {
	const [searchInput, setSearchInput] = useState('');
	const [feed, setFeed] = useState([]);
	const video = React.useRef(null); 
  const [status, setStatus] = React.useState({}); 
	useEffect(() => {
		fetch("http://157.230.11.142:5000/presentbox/00000000? 
                  text=Something%20Something%20Something&is_closed=true")
		.then(response => response.json())
      .then(data => setFeed(data));
		async function fetchStatus() {
			const status = await video.current.getStatusAsync();
			setStatus(status);
		}
		fetchStatus();
	}, []);
 const {width, height} = Dimensions.get('screen');
	return ( 
 
	<View style={styles.main}>
	  <View style={[styles.section, {height:height/1.7 }]}>
			<Text style={styles.heading}>
		   View Expression
			</Text>
			<View style={styles.search}>
				<TextInput value={searchInput} onChangeText= 
                                      {(val)=>setSearchInput=(val)} style={styles.input} 
                              placeholder="Search" placeholderTextColor="#000"/>
	          </View>
			 { fetch.length >  2 ? <ActivityIndicator size="large"  
                             color="#0000ff" /> :
			   <Video
        ref={video}
        style={styles.video} 
				posterSource={{ uri: 'https://i.imgur.com/7lkRQTl.png' }}
        source={{
          uri: 'http://157.230.11.142:5000/presentbox/download/00000000',
        }}
        useNativeControls
				resizeMode="cover" 
        isLooping
        onPlaybackStatusUpdate={status => setStatus(() => status)}
				onError={error => setStatus(() => ({ status, error }))} 
				
      />}
		</View>
      <View style={styles.buttons}>
        <TouchableOpacity 
            onPress={() =>
            status.isPlaying ? video.current.pauseAsync() : video.current.playAsync()
          }>
					
						{/* play button */}
				<View  style={styles.button} >{status.isPlaying ? <Ionicons name= "play-circle" size={52} color="#2c041c" /> :   <Ionicons name="pause-circle" size={52} />}</View>
				</TouchableOpacity>
      </View>
			 {/* display error when video is not playing */}
			 {status.error && <Text>{status.error ? 'not working' : 'works'}</Text>}
                  
		 <Message name="Hello World" feed={feed} />
		</View>
	);
};

export default Home;

const styles = StyleSheet.create({
	main: {
		flex: 1,
	},
	section: {
		backgroundColor: "#2c041c",
    borderBottomLeftRadius: 30,
		borderBottomRightRadius: 30,
		width: "100%",
	},
	feedText: {
		fontSize: 20,
		color: "#ffff",
		padding: 10,
		bottom: 0,
		left: 0,
		right: 0,

		position: "absolute",
		backgroundColor: "white",
	},
	video: {
		flex: 1,
		alignSelf: "stretch",
		height: "100%",
		width: "100%",
	},

	buttons: {
		flexDirection: "row",
		justifyContent: "center",
		alignItems: "center",
	},
	button: {
		fontSize: 14,
		fontWeight: "bold",
		borderWidth: 1,
		marginTop: 10,
		borderColor: "gray",
		alignItems: "center",
		maxWidth: "100%",
		borderRadius: 50,
		padding: 10,
	},
	heading: {
		fontSize: 24,
		fontFamily: "Montserrat_800ExtraBold",
		color: "#ffff",
		letterSpacing: 3,
		padding: 20,
		marginTop: 64,
	},
	input: {
		width: "90%",
		height: 40,
		borderRadius: 8,
		borderWidth: 1,
		backgroundColor: "#ebebeb",
		paddingLeft: 10,
		marginTop: 10,
		marginBottom: 10,
		fontSize: 16,
		fontFamily: "Montserrat_400Regular",
		letterSpacing: 1,
	},
	search: {
		display: "flex",
		alignItems: "center",
	},
	mainPostView: {
		width: "100%",
	},
	postTitle: {
		display: "flex",
		width: "90%",
		justifyContent: "space-between",
		backgroundColor: "#ededed",
		flexDirection: "row",
	},
	postView: {
		width: "100%",
		alignItems: "center",
		justifyContent: "space-between",
	},
});

PAGE I WANT TO PASS THE PROPS TO

import { StyleSheet, Text, View } from 'react-native';
import React from 'react';
import Message from '../components/Message';
import Home from './Home';

const Messages = () => {
	return (
		<View>
			<Message feed = {feed}/>
		</View>
	);
};

export default Messages;

const styles = StyleSheet.create({});

@kevinSmith

OK, that is too much information - reduce it down to the core issue.

This is not a specific RN issue - it is done the exact same way as React. Passing props is a fundamental issue in React.

It is not clear which props passing is the issue.

You say you want to pass it into Messages, but nothing seems to be calling that. I see this in there:

<Message feed = {feed}/>

Then in Message:

export default function Message({name,feed}) {

then feed would be passed in on props (which are destructured here) but name would be undefined.

Your other problem is that in Messages.js you are trying to pass a variable feed but it isn’t defined anywhere.

feed is a state variable in home ; i passed prop feed from home page to the component (message)it works for the home page …

my feed state is in my Home (parent component - a page)

i want to pass that feed to another page called (Messages)

i thought since message has prop feed which was passed from Home i can aswell pass it to Messages

ps : notice the difference between message and messages

Yes, this in Home.js

<Message name="Hello World" feed={feed} />

that makes sense to me.

This:

const Messages = () => {
	return (
		<View>
			<Message feed = {feed}/>
		</View>
	);
};

Makes no sense to me. feed is not defined in this file. It is not in scope (assuming this is all the code).

i want to pass that feed to another page called (Messages)

Where are you attempting this? You say you want to pass this into Messages, but I don’t see anywhere in your JSX where that is referenced.

i thought since message has prop feed which was passed from Home i can aswell pass it to Messages

You can pass anything you want to it. It doesn’t matter if Message has that prop or not. You can pass what you want to Messages and you can pass whatever you want to Message.

Just based on the common practices of React, I would expect Messages to receive an array of messages that then get mapped to the component Message.

feed is defined in another component called Home which has a state

const [feed, setFeed]= useState({})
it fetches an api and the i created a component called Message where i passed the fetch from home as a prop

thinking if i do so i can then pass that state to the other component

the component i want to pass to is Messages (with an s) so it also displays the feed been mapped

Right, then in React, I would expect to see something like:

<Messages feed={feed} />

somewhere. Where is that?

let me try that in the message
to see if it works

Wait, you want to put Messages in Message? Usually it would be the other way around. Usually you’d have a structure like:

Home
  Messages
    Message
    Message
    Message
    ...

Messages would get an array of messages (presumably a message is a string or an object) and Messages would map trough that array and render each individual Message.

sending image in a bit should help better

Home


–Hello World is from feed state ___

Messages.js component (page)
now i’m trying to pass the feed prop (state) to message which is blank

I really don’t understand what you want. Without talking about React, what is it you want.

Again, the name you have implies to me that you will have multiple messages and each will be shown inside the messages area. I don’t understand why you are showing a Message in Home and also want to do it in Messages. But maybe I am misunderstanding - please explain what you want to do.

That being said, instantiating components and passing values to them is a pretty basic topic in React - if I’m understanding what you are trying to do. I don’t know what your background is in React, but I might recommend reviewing some basic material.

Home page component has a video display …if video not working i display a message (which is from the state variable which fetches an api message eg feed.message will display a value of the api in home page )

now i also want to pass api from the state [feed, setFeed] to Messages component (a page) :

so what i was to pass the feed to a new component x (message without an s)
thinking that way i can pass it to messages … with the explanation please suggest as i read somewhere that state management might do the work

so what i was to pass the feed to a new component x (message without an s)
thinking that way i can pass it to messages

So, you want Messages to be inside Message? Conceptually that doesn’t make sense. Either you concept is off or your naming is.

i read somewhere that state management might do the work

There are more advanced state management tools, like Redux, etc. But this is a simple matter of passing props and structuring your project. You need to get the basics down first.

Have you done the FCC section on React?

no scrimba… forget the naming i think thats whats confusing

parent component A1 has * useState array (api) variable * which displays content in the parent page lets say a value from the usestate (api),

new component B2 page created : and wants to display content from the state in parent component pls how do i do this :

my logic was not good as i passed from parent A1 to child X and then wanted passing from child X to another parent b2

Hoping im able to explain better

PS: THANKS FOR THE RESPONSE / YOUR TIME

Can you draw out a tree diagram like I did above with the names of the components of what you want?

Again, have you done the FCC React curriculum? Passing props is something that is taught there, as it should be in any basic React course.

yes doing a study under FCC react

You should focus on learning the basics of React before trying to do a project. Being confused about how to pass props but wanting to do a project would be like a driving learner not knowing which pedal is the gas but wanting to drive in professional car race.

1 Like

Trying to answer, there are 2 possible cases:

  1. There is Home page and Message is its children, meaning the React component Home will render another component Messages as its child, Home will return a component . And then there is another component called Message, which is a child of Message, so the prop (feed) will go from its local (Home) to Messages (Home’s child) and to Message (Messages’s child). This is one that kevinSmith talking about right? And I think this is the case by looking at your code. (in your code, Home has Message as a child, not Messages, but it meant to be Home - Messages - Message?)
  2. There is Home component and Message component, these two are two different pages (or they call it screens if it is React Native), and you want to navigate between them.

For case 1:
You will prop the feed with,

<Message feed={feed} />

Then catch the prop in the Messages component as,

function Messages({feed}) {
return <p>{feed}</p>
}

Then in Messages component you can prop it again to its child,

function Messages({feed}) {
return <Message feed={feed} />
}

And finally get it in the Message component,

function Message({feed}) {
return <p1>{feed}</p1>
}

This is 2 step prop-ping. Prop always flow from parent to children, this is de way.

For case 2:
You can use programmatic navigation useNavigate, but you need to use React Router here to define the address/path of each page, then you can navigate between the pages with, (example are arbitrary path to make it clear)

const navigate = useNavigate()
navigate(`/users/:${id}`, {name: "name", address: "address"})

here I demonstrate how to navigate to other pages using useNavigate, first argument is its path as defined by React Router, second arg is a payload object, and you can accept them from the page you are going into with useLocation, useParams hooks or {navigation, route} props, the path can also bring something like params and query so if your data is simple string I think it is better to use path to carry it instead of object payload, I don’t this is the case? I think this might be useful for you since you are dealing with an app, and an app because of small screen need to navigate back and forth between various pages, sometime need to send data as payload.

Hope this help.

had to use context to fix it