I have a problem with making my ButtonGroup dynamic, I tried a lot but nothing seems to work, can someone help me, please?
import React from 'react';
import { ButtonGroup } from 'react-native-elements';
export default class WebsiteFilter extends React.Component {
constructor(props) {
super(props);
this.state = {
WebsiteFilter: 3
};
}
updateIndex = ( WebsiteFilter ) => this.setState({ WebsiteFilter })
render() {
const buttons= ['Vergelijkdirect', 'Ivanhoe', 'Bespaarcoach'];
let { WebsiteFilter } = this.state;
return (
<ButtonGroup
textStyle={{ textAlign: 'center', fontSize: 12, }}
onPress={this.updateIndex}
WebsiteFilter={WebsiteFilter}
buttons={buttons}
/>
);
}
}
Instead of:
const buttons= ['Vergelijkdirect', 'Ivanhoe', 'Bespaarcoach'];
I need to display the domain of this array:
[{"id":127,"created_at":"2015-11-02 15:35:11","updated_at":"2016-09-19 11:42:10","deleted_at":null,"customer_id":66,"domain":"http:\/\/vergelijkdirect.com","google_id":"UA-97758230-1","currency_id":1,"root":1,"screenshot":"","integration_date":"2016-09-19 11:42:10"},{"id":283,"created_at":"2017-01-13 16:54:24","updated_at":"2017-01-13 16:54:24","deleted_at":null,"customer_id":66,"domain":"https:\/\/ivanhoe.io","google_id":null,"currency_id":1,"root":0,"screenshot":"","integration_date":null},{"id":327,"created_at":"2017-06-14 19:29:42","updated_at":"2017-06-23 17:29:01","deleted_at":null,"customer_id":66,"domain":"http:\/\/bespaarcoach.vergelijkdirect.com","google_id":"UA-39848260-2","currency_id":1,"root":0,"screenshot":"","integration_date":"2017-06-23 17:29:01"}]
The property buttons expects an array of strings or components, so in your case, you need to map the array and to return the property that you want to display:
data.map(e => e.id)
Also, the ButtonGroup component does not have a property WebsiteFilter, it has to be selectedIndex.
Your component should look like this:
<ButtonGroup
textStyle={{ textAlign: 'center', fontSize: 12, }}
onPress={this.updateIndex}
selectedIndex={this.state.WebsiteFilter}
buttons={data.map(e => e.id)}
/>
Here is a working demo.
Related
I want to understand why my Text is not rendering please and how i can get this working
import React, { Component } from 'react';
import { View,Button,Text } from 'react-native';
export default class LiveApiData extends Component {
constructor() {
super()
this.state = {data:[]}
}
componentDidMount() {
fetch("<<taking out the api key")
.then(response => response.json())
.then(new_data => {this.setState({data:new_data})})
}
render() {
return (
<View style={{ height: 200, flexDirection: 'row'}}>
<Text> {this.state.data[0]}</Text>
</View>
);
}
}
Much appreciated in advance
In the above code in the render() you are rendering the data which is an array so. If this array is a collection of objects you will need to specify the key name to render the text. If the array is of strings then it should get rendered.
I am pasting a working example for this question.Example Link
The solution will add a null check. Because the state will be empty when you are rendering at the first time.
<div style={{ height: 200, flexDirection: "row" }}>
<div> {this.state.data.length ? this.state.data[0].title : ""}. </div>
</div>
I am starting to learn sliders and other basic components in react native. I would like to print the current value of the slider in the terminal. I tried putting console.log() in different places, but didn't know what I was doing and got errors.
import React, { Component } from 'react';
import { Slider, View, Text } from 'react-native';
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
sliderValue: "0",
};
}
render() {
return (
<View
style={{
flex: 1,
padding: 20,
justifyContent: "center",
backgroundColor: "#ecf0f1",
}}>
<Text style = {{ color: "black" }}>
Value of this slider is : {this.state.sliderValue}
</Text>
<Slider
maximumValue = {10}
minimumValue = {0}
step = {1}
value = {this.state.sliderValue}
onValueChange = {sliderValue => this.setState({ sliderValue })}
/>
</View>
);
}
}
Well, you have many options here, I'll give you 2.
You can just console log in your render method
render() {
console.log(this.state.sliderValue);
//the reset of your code
}
Or you can do it inline with the setState call
onValueChange = {sliderValue => console.log(sliderValue) || this.setState({ sliderValue })}
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>
)
}
}
I have a component to add todos AddTodo which works fine and update the state with my added todos and I have a component TodoItems to display the todos in <FlatList/>. I'm using React Native Tab Navigator to switch between components but I'm not sure how to send the state this.state.todos from AddTodo component to TodoItems component.
I have been researching but couldn't find a solution in Tab Navigator but there are plenty of solutions for Stack Navigator.
Component AddTodo
export default class AddTodo extends Component {
constructor(props) {
super(props);
this.state = {
todoText: null,
todos: []
}
}
onAdd = () => {
if (this.state.todoText) {
this.state.todos.push({'todoItem': this.state.todoText});
this.setState({todos: this.state.todos});
}
}
render() {
return(
<View>
<TextInput onChangeText={(text) => {
this.setState({todoText: text});
}} />
<TouchableOpacity onPress={() => {
this.onAdd;
}}>
</View>
);
}
}
Component TodoItems
export default class TodoItems extends Component {
constructor(props) {
super(props);
this.state = {
todosList: []
}
}
render() {
return(
<View>
<FlatList
data={this.state.todosList}
renderItem={(item, index) => {
<Text>{item.todoItem}</Text>
}}
/>
</View>
);
}
}
Component Tabs
import {TabNavigator} from 'react-navigation';
import AddTodo from "./AddTodo";
import TodoItems from "./TodoItems";
var myTabs = TabNavigator(
{
'AddTodo':{screen: AddTodo,},
'TodoItems':{screen: TodoItems, },
},
{
tabBarPosition: 'top',
swipeEnabled: false,
tabBarOptions: {
labelStyle:{
fontSize: 13,
fontWeight: 'bold',
},
indicatorStyle: {
borderBottomColor: '#003E7D',
borderBottomWidth: 2,
},
style:{
backgroundColor: '#F30076',
elevation: 0,
},
},
});
export default myTabs;
Well I think you have two options:
You can use Redux which allows you to globalise your state objects so you can use them all over your app, but it can be rather complicated
https://redux.js.org/
Or you can render TodoItems from within AddTodo:
render() {
return(
<View>
<TextInput onChangeText={(text) => {
this.setState({todoText: text});
}} />
<TouchableOpacity onPress={() => {
this.onAdd;
}}>
</View>
<TodoItems data={this.state.todos} />
);
}
Then you can access that data from within TodoItems:
Hope this helps!
Note: I am new to React Native and have searched up how to do this but found no helpful results I am using React Native to create an app and want to add multiple components, such as text, buttons, and a text input space, but am having trouble doing so without receiving errors. Is there any way to include multiple components into one javascript document using React Native?
The code I currently have:
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
export default class App extends React.Component {
render() {
return (
<View style={{alignItems: 'center'}}>
<Text style={styles.bigblack}>Sample Bold Text Here</Text>
<Text>Sample Text Here:</Text>
</View>
);
}
}
const styles = StyleSheet.create({
bigblack: {
color: 'black',
fontWeight: 'bold',
fontSize: 28,
},
red: {
color: 'red',
},
container: {
flex: 1,
backgroundColor: '#fdf5e6',
alignItems: 'center',
justifyContent: 'center',
},
});
Code I want to add for Text Input:
class UselessTextInput extends Component {
render() {
return (
<TextInput
{...this.props}
editable = {true}
maxLength = {40}
/>
);
}
}
export default class UselessTextInputMultiline extends Component {
constructor(props) {
super(props);
this.state = {
text: 'Useless Multiline Placeholder',
};
}
render() {
return (
<View style={{
backgroundColor: this.state.text,
borderBottomColor: '#000000',
borderBottomWidth: 1 }}
>
<UselessTextInput
multiline = {true}
numberOfLines = {4}
onChangeText={(text) => this.setState({text})}
value={this.state.text}
/>
</View>
);
}
}
Code I want to add for Button:
<Button
onPress={onPressLearnMore}
title="Learn More"
color="#841584"
accessibilityLabel="Learn more about this button"
/>
You can create multiple component in same document but can export default only one.
So you can create multiple component like below:
export class UselessTextInput {}
export class UselessTextInputMultiline {}
export class Button {}
while accessing :
import {UselessTextInput, UselessTextInputMultiline, Button} from './components/customInput' // change with your respective path
if you still want to have single export default then:
export default class UselessTextInputMultiline {}
and while importing
import Template,{Button} from './components/customInput'
For, exporting multiple component:
module.exports = {
text: UselessTextInput,
btn: Button
}
imports will be like:
let txtInput= require('./components/customInput').text;
let btnInput = require('./components/customInput').btn;