Display variable inside my render React Native - javascript

I was trying to display data from a fetch function to my render app in react native.
I was able to get the data from my fetch but i am not able to display it on the app..
this is my code:
import React from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
export default function App() {
const fetchDatos = async () => {
return fetch('http://localhost:8000/api/consulta').then(response => {
return response.json();
})
.then(responseJson => {
var Nombre = responseJson.Participante.InfoParticipante['#attributes'].Nombre;
});
}
return (
<View>
<Button
title='press me'
onPress={fetchDatos}
/>
<Text>{Nombre}</Text>
</View>
);
}
As you can see in the code above I get the data stored in the var ''Nombre'' and I am trying the display it in the app but it's telling me Uncaught ReferenceError: Nombre is not defined
Does anyone know how to fix this, I would appreciate it a lot!

This will work
import React,{useState} from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
export default function App() {
const [nombre,setNombre]=useState()
const fetchDatos = () => {
return fetch('http://localhost:8000/api/consulta').then(response => {
return response.json();
})
.then(responseJson => {
setNombre(responseJson.Participante.InfoParticipante['#attributes'].Nombre);
});
}
return (
<View>
<Button
title='press me'
onPress={fetchDatos}
/>
<Text>{nombre}</Text>
</View>
);
}

Related

how to call provider function in child with react native?

I have two components. One is the provider and the second is a child. Now I want to use the function of provider in the child but with my current approach, it says that function is undefined. Can you see what I'm doing wrong?
Here is the code below.
import React from 'react';
import { View, TouchableOpacity, Text } from 'react-native';
const MyProvider = (props) => {
const { children } = props;
const handlePress = () => {
console.log("Provider component function called!");
};
return (
<View>
{children}
</View>
);
};
const NoLocationAccess = (props) => {
const { handlePress } = props;
console.log("handlePress : ",handlePress)
return (
<TouchableOpacity onPress={handlePress}>
<Text>I am the child component</Text>
</TouchableOpacity>
);
};
export default NoLocationAccess;
I have tried provider.wrapper. that made things more problematic.
To call a function, that is defined in the provider, from the child you need too pass it down as a prop.
Here the modified Code:
import React from 'react';
import { View, TouchableOpacity, Text } from 'react-native';
const MyProvider = (props) => {
const { children } = props;
const handlePress = () => {
console.log("Provider component function called!");
};
return (
<View>
{React.Children.map(children, (child) => {
return React.cloneElement(child, { handlePress });
})}
</View>
);
};
const NoLocationAccess = (props) => {
const { handlePress } = props;
console.log("handlePress : ",handlePress)
return (
<TouchableOpacity onPress={() => handlePress()}>
<Text>I am the child component</Text>
</TouchableOpacity>
);
};
export default NoLocationAccess;
Try it
It took me a while. but I have done this high-order component. this idea came to mind with the redux connect method. so took that approach and created a higher-order component. that works flawlessly.
Here is the solution.
High-Order Component.
import React from 'react';
import { View, TouchableOpacity, Text } from 'react-native';
const MyProvider = (props) => {
class GPSComponent extends React.Component {
componentDidMount() {
}
requestPermissions= async()=> {
console.log("i is called",this.props.userCurrentLocation)
}
render() {
return <WrappedComponent
requestPermissions={this.requestPermissions}
{...this}
/>;
}
}
return GPSComponent;
};
child component.
import React from 'react';
import { View, TouchableOpacity, Text } from 'react-native';
import MyProvider from "./MyProvider"
const NoLocationAccess = (prop) => {
const { requestPermissions } = prop;
console.log("requestPermissions ",requestPermissions)
return (
<TouchableOpacity onPress={requestPermissions}>
<Text>I am the child component</Text>
</TouchableOpacity>
);
};
export default MyProvider(NoLocationAccess);

Array of objects do not render using setState and map

I am using typescript in a react-native project, and would like to render an array of objects that come from a query using AWS-Amplify, using the map function.
I use setState (here setTracks) to declare my state.
While it logs well in the console, the map function does not render anything.
Here is the code:
import {useEffect, useState} from 'react';
import {
ScrollView,
SafeAreaView,
StyleSheet,
Image,
TouchableWithoutFeedback,
ImageBackground,
Dimensions
} from "react-native";
import EditScreenInfo from '../components/EditScreenInfo';
import { Text, View } from '../components/Themed';
import Amplify from 'aws-amplify'
import config from './aws-exports'
Amplify.configure(config)
import { API, graphqlOperation } from 'aws-amplify'
import { listTracks } from '../src/graphql/queries'
export default function TabTwoScreen() {
const [tracks, setTracks] = useState<Array>([])
//const [tracks, setTracks] = useState([])
useEffect(() => {
fetchTracks()}, [])
async function fetchTracks() {
try {
const trackData = await API.graphql(graphqlOperation(listTracks))
console.log('trackData:', trackData.data.listTracks.items)
setTracks([trackData])
console.log('trackdata is: ', tracks)
} catch (err) {
console.log('error fetching tracks...', err)
}
};
return (
<SafeAreaView style={styles.container}>
{
tracks.map((track, index) => (
<View key={index} style={styles.item}>
<Text style={styles.name}>{track.song}</Text>
<Text style={styles.description}>{track.artist}</Text>
<Text style={styles.city}>{track.songUrl}</Text>
</View>
))
}
</SafeAreaView>
)
}```

FlatList does not render any text in react-native

I'm fairly new to react native and redux and was trying to render the library title from a JSON file in a flat list using redux, but my FlatList component does not render anything on the screen.
here's my code :
LibraryList.js
import React, { Component } from "react";
import { FlatList } from "react-native";
import { connect } from "react-redux";
import ListItem from "./ListItem";
class LibraryList extends Component {
renderItem(library) {
return <ListItem library={library} />;
}
render() {
return (
<FlatList
data={this.props.libraries}
renderItem={this.renderItem}
keyExtractor={library => library.id}
/>
);
}
}
const mapStateToProps = state => {
return { libraries: state.libraries };
};
export default connect(mapStateToProps)(LibraryList);
ListItem.js
import React, { Component } from "react";
import { Text } from "react-native";
import { CardSection } from "./common";
class ListItem extends Component {
render() {
return (
<CardSection>
<Text>{this.props.library.title}</Text>
</CardSection>
);
}
}
export default ListItem;
App.js
import React from "react";
import { View } from "react-native";
import { Provider } from "react-redux";
import { createStore } from "redux";
import reducers from "./reducers";
import { Header } from "./components/common";
import LibraryList from "./components/LibraryList";
const App = () => {
return (
<Provider store={createStore(reducers)}>
<View>
<Header headerText="Tech Stack" />
<LibraryList />
</View>
</Provider>
);
};
export default App;
The JSON file is like
[
{
"id": '' ,
"title": '' ,
"description":''
},
{
"id":'' ,
"title":'' ,
"description":''
}
]
I read some solutions for this suggesting changing the renderItem function to something like this
renderItem = ({ library }) => <ListItem library={library} />
still does not work. Can someone help me with this problem?
Thanks.
You have to make your renderItem as an arrow function. Otherwise you have to bind your function inside constructor in order to access function as renderItem={this.renderItem}.
import React, { Component } from 'react';
import { FlatList } from 'react-native';
import { connect } from 'react-redux';
import ListItem from './ListItem';
class LibraryList extends Component {
renderItem = ({ item }) => {
return <ListItem library={item} />
}
render() {
return (
<FlatList
data={this.props.libraries}
renderItem={this.renderItem}
keyExtractor={library => library.id}
/>
);
}
}
const mapStateToProps = state => {
return { libraries: state.libraries };
};
export default connect(mapStateToProps)(LibraryList);
or you can call your renderItem as an arrow function inside render like below
renderItem={(item) => this.renderItem(item)}
but using an arrow function in render creates a new function each time the component renders, which may break optimizations based on strict identity comparison.
Hope this helps you. Feel free for doubts.
In your flatlist try thi s:
<FlatList
data={this.props.libraries}
renderItem={({item, index}) => {
this.renderItems(item); // change this name to renderItems so that it doesnt clash with flatlist default renderItem
}}
/>
Hope it helps. feel free for doubts
You have several approaches to your problem.
Firstly your renderItem should be binded, so either do this
renderItem = (library) => {
or this
renderItem={this.renderItem.bind(this)}
besides the binding problem, flatlist prop renderItem will return to your function an object with this structure
{ item, index }
so in reality your renderItem should be like this
renderItem({ item }){
return <ListItem library={item} />;
}

Variable won't be set inside the fetch function

I am trying to print text content of login.php into the screen via "var result", but the fetch function won't alter value of "var result". How can I set value of result from output of the fetch function?
import React, { Component } from 'react';
import {
StyleSheet,
Text,
View,
StatusBar,
} from 'react-native';
import Logo from '../components/Logo';
import Form from '../components/Form';
import loginapi from '../apis/loginapi';
var result='noresult';
export default class Login extends Component<{}> {
render() {
login();
return (
<View style={styles.container}>
<Logo/>
<Form/>
<Text>
{result}
</Text>
<Text>
</Text></View>
);
}
}
function login() {
result = fetch('https://www.skateandstrike.com/loginsv/login.php').then((text) => {return text;});
}
const styles = StyleSheet.create({
container : {
backgroundColor:'#f05545',
flex: 1,
alignItems:'center',
justifyContent:'center',
}
});
function myFunction() {
this.setState({ showLoading: false });
}
This is not working too, using setState:
import React, { Component } from 'react';
import {
StyleSheet,
Text,
View,
StatusBar,
} from 'react-native';
import Logo from '../components/Logo';
import Form from '../components/Form';
import loginapi from '../apis/loginapi';
export default class Login extends Component<{}> {
constructor(){
super();
this.state = {
data:'NoData',
}
}
render() {
login();
return (
<View style={styles.container}>
<Logo/>
<Form/>
<Text>
{this.state.data}
</Text>
</View>
);
}
}
function login() {
fetch('https://www.skateandstrike.com/loginsv/login.php').then(data => this.setState(data));
}
const styles = StyleSheet.create({
container : {
backgroundColor:'#f05545',
flex: 1,
alignItems:'center',
justifyContent:'center',
}
});
function myFunction() {
this.setState({ showLoading: false });
}
Am I using setState in a wrong way? Thanks in advance for your help.
When using the fetch API, I'd recommend using a promise, and you parse it if you are setting the state.
React re-renders on state/props change.
sample code:
fetch(url)
.then(data => data.json()) // if needed
.then(data => this.setState(data))
remember to set state in the constructor.

listview and fetch react native not working

I'm trying to load info from a json file using fetch and displaying data using a Listview React native component. Data from fetch is already load on my this.state.films, because if I try
<Text>{this.state.films[0].title}</Text>
I get the name of the film and that is ok. But when I try a Listview I only get "[]".
What am I doing wrong?? Actually I'm following React native doc and I am trinying to join two sections: "Networking" and "Using a list view". I took json from there.
Please Help,
Thanks!
That my code index.windows.js
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
Image,
TextInput,
ListView
} from 'react-native';
class AwesomeProject extends Component {
constructor(props) {
super(props)
this.state = { films: [] }
const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
}
componentWillMount() {
fetch('http://facebook.github.io/react-native/movies.json')
.then((response) => {
return response.json()
})
.then((movies) => {
this.setState({ films: ds.cloneWithRows(movies.movie) })
})
}
render() {
return (
<View style={{paddingTop: 22}}>
<ListView
dataSource={this.state.films}
renderRow={(rowData) => <Text>{rowData.title}</Text>}
/>
</View>
);
}
}
AppRegistry.registerComponent('AwesomeProject', () => AwesomeProject);
React Native has a simpler solution, a FlatList, which works nicely, and wraps around the ListView. It can be used like this:
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
Image,
TextInput,
FlatList
} from 'react-native';
class AwesomeProject extends Component {
state = {
films: []
}
componentWillMount() {
fetch('http://facebook.github.io/react-native/movies.json')
.then( response => response.json())
.then((films) => {
this.setState({ films })
})
}
render() {
return (
<View style={{paddingTop: 22}}>
<FlatList
data={this.state.films}
renderItem={({item}) => <Text>{item.title}</Text>}
/>
</View>
);
}
}
AppRegistry.registerComponent('AwesomeProject', () => AwesomeProject);

Categories