How to use item.key in other component instead of alert - javascript

FlatList Component working complete if i click Android it show in Android in aler but i have to pass that bind value into Subscribe component instead of alert.
should i have to pass data into state and for use it as a props in other component ?
import React, { Component } from 'react';
import { AppRegistry, FlatList, StyleSheet, Text, View,Alert } from 'react-native';
export default class FlatList extends Component {
constructor(props) {
super(props);
this.updateKey = this.updateKey.bind(this);
this.state = {};
}
updateKey(keyData) {
this.setState({ keyData: keyData });
}
getListViewItem = (item) => {
Alert.alert(item.key);
}
render() {
return (
<View style={styles.container}>
<FlatList
data={[
{key: 'Android'},{key: 'iOS'}, {key: 'Java'},{key: 'Swift'},
{key: 'Php'},{key: 'Hadoop'},{key: 'Sap'},
]}
renderItem={({item}) =>
<Text style={styles.item}
onPress={this.getListViewItem.bind(this, item)}>{item.key}</Text>}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
item: {
padding: 10,
fontSize: 18,
height: 44,
},
})
AppRegistry.registerComponent('flatList', () => FlatList);
import React, { Component } from 'react'
import { View, Item } from 'react-native';
export default class Subscribe extends Component {
render() {
return (
<View>
<Text>{item.key}</Text>
</View>
)
}
}

Yes, if you want to pass it as prop to a child component you can set it inside your state and pass it to the child component you are talking about.
To accomplish this you just have to change your Alert to: this.setState( { selectedValue: item } )
Then your child would look something like:
<Child item = {this.state.selectedValue} />
And you will be able to access it in your child simply doing:
this.props.item

Related

Getting value from user with textInput and assigning to variable (React-Native)

Here I want to assign the data from textInput to variable a. How can I do it?
(That is, when the user enters data in textInput, I want to assign it to variable a.)
import React, { Component } from 'react'
import { Text, View, TextInput} from 'react-native'
export default class deneme1 extends Component {
constructor(props) {
super(props);
this.state = {
a:"",
};
}
render() {
return (
<View>
<View style={styles.textinput}>
<TextInput
placeholderTextColor='white'
style={styles.textinputtext}
/>
</View>
</View>
)
}
}
You can try this one
<TextInput
placeholder={"A Variable"}
onChangeText={(text) => this.setState({a: text}) }
value={this.state.a}
/>

My React Component state is continuously return null object

I trying to build a weather app for my training and I have a issues.
I got a Type Error whatever I do. what I intended to do is get a json data from weathermap api and then
show some strings but I couldn't.
here is main content from My app
import React, { Component } from 'react';
import { View, StyleSheet, Text } from 'react-native';
class Content extends Component{
constructor(props) {
super(props);
this.state = {
data: this.props.weather.main,
};
}
render() {
return (
<View style={styles.content}>
<Text style={styles.city}>City Name</Text>
<Text style={styles.itemsize}>Weather {this.state.data}</Text>
<Text style={styles.itemsize}>Description</Text>
<Text style={styles.itemsize}>Temperature Celsius</Text>
<Text style={styles.itemsize}>Pressure</Text>
<Text style={styles.itemsize}>Humidity</Text>
</View>
);
}
}
const styles = StyleSheet.create({
content: {
flex: 1,
justifyContent: 'center',
alignItems:'center'
},
city: {
fontSize: 50,
padding: 20
},
itemsize: {
fontSize: 30,
padding: 5
}
})
export default Content;
and this is my upper component which is trying to get data and pass down.
import React, { Component } from 'react';
import Content from './Content';
import GetWeather from './GetWeather';
class Home extends Component {
constructor(props) {
super(props);
this._getData.bind(this);
this._getData();
this.state = {
data: null,
};
}
_getData = () => {
GetWeather.getWeather().then( json => {
console.log(json);
this.setState({data: json});
});
};
render() {
return (
<Content weather={this.state.data}/>
);
}
}
export default Home;
and last one is code that I wrote to get api data from openweathermap
function getLocation(lat, long) {
return `${API_STEM}lat=${lat}&lon=${long}&appid=${APP_ID}`;
}
function getWeather() {
return fetch(getLocation(LATTITUDE,LONGGITUDE))
.then(response => response.json())
.then(responseJson => {
return { main: responseJson.weather[0].main};})
.catch(err =>console.log(err));
}
export default {getWeather: getWeather};
In your parent component, state never gets data and always remains null. When we want to fetch data from an API, we should use a react lifecycle method called componentDidMount(). So in your parent component, you should either call your _getdata function in componentDidMount or fetch your data in the lifecycle method, like below code which is a better way in my opinion. Also, never initially set your state to null. set it to an empty object.
import React, { Component } from 'react';
import Content from './Content';
import GetWeather from './GetWeather';
class App extends Component {
constructor(props) {
super(props);
this.state = {
data: {},
};
}
componentDidMount() {
GetWeather.getWeather().then( json => {
console.log(json);
this.setState({data: json});
});
}
render() {
console.log(this.state.data);
return (
<Content weather={this.state.data}/>
);
}
}
export default App
and then in your child component, you should either use one of updating lifecycle methods (that has risks) or you can change your child component to functional component, for you don't need state.
import React, { Component } from 'react';
import { View, StyleSheet, Text } from 'react-native';
function Content(props) {
return (
<View style={styles.content}>
<Text style={styles.city}>City Name</Text>
<Text style={styles.itemsize}>Weather {props.weather.main}</Text>
<Text style={styles.itemsize}>Description</Text>
<Text style={styles.itemsize}>Temperature Celsius</Text>
<Text style={styles.itemsize}>Pressure</Text>
<Text style={styles.itemsize}>Humidity</Text>
</View>
)
}
const styles = StyleSheet.create({
content: {
flex: 1,
justifyContent: 'center',
alignItems:'center'
},
city: {
fontSize: 50,
padding: 20
},
itemsize: {
fontSize: 30,
padding: 5
}
})
export default Content;
The main problem is that this.state.data in the Home component is set after the Content component is created (after its constructor function is called).
This will generate a TypeError because this.props.weather is undefined and you are trying to access a property this.props.weather.main.
The easiest way to solve this will be to use the props object directly instead of adding those props to the state, here is an example:
<Text style={styles.itemsize}>Weather {this.props.weather}</Text>
Before the request finishes you already set this.state.data inside Content to null and it will not get updated when the component re-renders because the constructor only runs once on mount.
Setting state from props is an anti pattern and should be used only in rare situations.
Instead, read the weather data from this.props which will get updated once the parent component updates his state
You would also need to check if this.props.weather is null before you access .main inside this.props.weather
class Content extends Component {
render() {
const { weather } = this.props
return (
<View style={styles.content}>
<Text style={styles.city}>City Name</Text>
<Text style={styles.itemsize}>
Weather {weather ? weather.main : null}
</Text>
<Text style={styles.itemsize}>Description</Text>
<Text style={styles.itemsize}>Temperature Celsius</Text>
<Text style={styles.itemsize}>Pressure</Text>
<Text style={styles.itemsize}>Humidity</Text>
</View>
)
}
}

Call component through function React Native

I'm developing a component to publish it in npm, but I'd like to call my component using a method instead of a tag.
Example:
myComponent.js
import React from 'react'
import { View, Text } from 'react-native'
export const showComponent = () => {
// this would be the function that I user to call my component down
}
const myComponent = (props) => {
return(
<View>
<Text>Oi</Text>
</View>
)
}
App.js
import React from 'react'
import { View, Text, TouchableOpacity } from 'react-native'
import { showComponent } from 'my-component'
const App = () => {
return(
<View>
<TouchableOpacity onPress={() => showComponent()}>
<Text>Home</Text>
</TouchableOpacity>
</View>
)
}
export defaul App
the idea is that when calling the showComponent function I show my component, and when I call, for example, the hide function, I close my component.
You can do it using a single class export:
import * as React from 'react';
export default class MyComponent extends React.Component {
state = {
isOpen: false,
};
open = () => {
this.setState({ isOpen: true });
};
close = () => {
this.setState({ isOpen: true });
};
render() {
const { isOpen } = this.state;
return !isOpen ? null : (
<View>
<Text>Oi</Text>
</View>
);
}
}
And you use it like so:
<MyComponent ref={(x) => this.myComponent = x)} />
And you open it like so:
this.myComponent.open();
I see in a comment above you want to call the component with a redux action, so you should call your redux action in that on click, but the component you want to show/hide needs to be linked to a redux state variable. Then in your jsx you'd have:
<View>
<TouchableOpacity onPress={() => showComponent()}>
<Text>Home</Text>
</TouchableOpacity>
{reduxBoolean && <MyComponent />}
</View>
import React from 'react'
import { View, Text} from 'react-native'
const example = (props) => {
return (
<View>
<Text>Hello</Text>
</View>
)
}
// props
import React from 'react'
import { View, Text} from 'react-native'
const examples = () => {
return(
<View>
<Text><example/></Text>
</View>
)
}
and print is : Hello

How To Get Props in another Screen in react navigation?

I have an issue with react-navigation in passing the props to another screen,
I need to pass some props to Detail screen when the user presses one of the List Places I need to push screen with some details about the place like a Name of place and Image of place,
Errors :
this is my Code
Reducer
import { ADD_PLACE, DELETE_PLACE } from "../actions/actionTypes";
const initialState = {
places: []
};
import placeImage from "../../assets/img.jpg";
const reducer = (state = initialState, action) => {
switch (action.type) {
case ADD_PLACE:
return {
...state,
places: state.places.concat({
key: Math.random(),
name: action.placeName,
// image: placeImage,
image: {
uri:
"https://images.unsplash.com/photo-1530009078773-9bf8a2f270c6?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=750&q=80"
}
})
};
case DELETE_PLACE:
return {
...state,
places: state.places.filter(place => {
return place.key !== state.selectedPlace.key;
})
};
default:
return state;
}
};
export default reducer;
Place List Component
import React from "react";
import { FlatList, StyleSheet, ScrollView } from "react-native";
import ListItem from "../ListItem/ListItem";
const PlaceList = props => {
return (
<FlatList
style={styles.listContainer}
data={props.places}
renderItem={info => (
<ListItem
placeName={info.item.name}
placeImage={info.item.image}
onItemPressed={() => props.onItemSelected(info.item.key)}
/>
)}
keyExtractor={index => String(index)}
/>
);
};
export default PlaceList;
Find Place Screen
import React, { Component } from "react";
import { View, Text } from "react-native";
import { connect } from "react-redux";
import { StackActions } from "react-navigation";
import PlaceList from "../../Components/PlaceList/PlaceList";
class FindPlaceScreen extends Component {
constructor() {
super();
}
itemSelectedHandler = key => {
const selPlace = this.props.places.find(place => {
return place.key === key;
});
this.props.navigation.push("PlaceDetail", {
selectedPlace: selPlace,
name: selPlace.name,
image: selPlace.image
});
};
render() {
return (
<View>
<PlaceList
places={this.props.places}
onItemSelected={this.itemSelectedHandler}
/>
</View>
);
}
}
const mapStateToProps = state => {
return {
places: state.places.places
};
};
export default connect(mapStateToProps)(FindPlaceScreen);
Place Details Screen
import React, { Component } from "react";
import { View, Text, Image, TouchableOpacity, StyleSheet } from "react-native";
import Icon from "react-native-vector-icons/Ionicons";
class PlaceDetail extends Component {
constructor(props) {
super(props);
}
render() {
return (
<View style={styles.modalContainer}>
<View>
<Image
source={this.props.navigation.state.params.image}
style={styles.placeImage}
/>
<Text style={styles.placeName}>
{this.props.navigation.state.params.namePlace}
</Text>
</View>
<View>
<TouchableOpacity onPress={props.onItemDeleted}>
<View style={styles.deleteButton}>
<Icon size={30} name="ios-trash" color="red" />
</View>
</TouchableOpacity>
<TouchableOpacity onPress={props.onModalClosed}>
<View style={styles.deleteButton}>
<Icon size={30} name="ios-close" color="red" />
</View>
</TouchableOpacity>
</View>
</View>
);
}
}
export default PlaceDetail;
You need to use react-native-navigation v2 for the find place screen
itemSelectedHandler = key => {
const selPlace = this.props.places.find(place => {
return place.key === key;
});
Navigation.push(this.props.componentId, {
component: {
name: 'PlaceDetail',
options: {
topBar: {
title: {
text: selPlace.name
}
}
},
passProps: {
selectedPlace: selPlace
}
}
});
};
make sure you import { Navigation } from "react-native-navigation";
Your PlaceDetail has some error
<TouchableOpacity onPress={props.onItemDeleted}>
<TouchableOpacity onPress={props.onModalClosed}>
Change props to this.props
<TouchableOpacity onPress={this.props.onItemDeleted}>
<TouchableOpacity onPress={this.props.onModalClosed}>
But I don't see onItemDeleted and onModalClosed anywhere, don't forget to pass those to PlaceDetail via props as well :)

Trouble getting function from different component

I'm new to react native. I am trying to get a 'Key' from a different component. I mean I am trying to call a function from a different component, as a parent component. But, I'm totally jumbled with all these reference calls and all. Please suggest to me how to call a function from a different component.
// AddScreen.js
import React, { Component } from 'react';
import { AppRegistry, AsyncStorage, View, Text, Button, TextInput, StyleSheet, Image, TouchableHighlight, Linking } from 'react-native';
import styles from '../components/styles';
import { createStackNavigator } from 'react-navigation';
import History from '../components/History';
export default class AddScreen extends Component {
constructor(props) {
super(props);
this.state = {
myKey: '',
}
}
getKey = async () => {
try {
const value = await AsyncStorage.getItem('#MySuperStore:key');
this.setState({ myKey: value });
} catch (error) {
console.log("Error retrieving data" + error);
}
}
async saveKey(value) {
try {
await AsyncStorage.setItem('#MySuperStore:key', value);
} catch (error) {
console.log("Error saving data" + error);
}
}
componentDidMount() {
this.getKey();
}
render() {
const { navigate } = this.props.navigation;
return (
<View style={styles.MainContainer}>
<View style={styles.Date_input}>
<TextInput
placeholder="Add input"
value={this.state.myKey}
onChangeText={(value) => this.saveKey(value)}
/>
</View>
<View style={styles.getKeytext}>
<Text >
Stored key is = {this.state.myKey}
</Text>
</View>
<View style={styles.Historybutton}>
<Button
onPress={() => navigate('History')}
title="Press Me"
/>
</View>
</View>
)
}
}
//History.js
import React, { Component } from 'react';
import AddScreen from '../components/AddScreen';
import {
AppRegistry,
StyleSheet,
Text,
TextInput,
Button,
View,
AsyncStorage
} from 'react-native';
export default class History extends Component {
constructor(props) {
super(props);
this.state = {
myKey: ''
}
}
render() {call async function synchronously
return (
<View style={styles.container}>
<Button
style={styles.formButton}
onPress={this.onClick}
title="Get Key"
color="#2196f3"
accessibilityLabel="Get Key"
/>
<Text >
Stored key is = {this.state.mykey}
</Text>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
padding: 30,
flex: 1,
backgroundColor: '#F5FCFF',
},
});
I just want to call the getKey function from the History component to get the myKey value on the History component's screen.
Please suggest to me, by taking my components as an example.
You just simply need to pass the key via navigation parameters.
<Button
onPress={() => navigate('History', { key: this.state.myKey })}
title="Press Me"
/>
and in your history component you can do
render() {
const key = this.props.navigation.getParam('key');
return (
// other code
)
}
You can read more about passing parameters here. https://reactnavigation.org/docs/en/params.html

Categories