I am creating dinner decider app and want to add items into an array from the user input. input added to an array list and shows in alert box but not reloat the FlatList. Please help
Here is my code for the same.
constructor(props){
super(props);
this.state = {items:[{key:'Pasta'},{key:'Pizza'}],userdata:''}
}
render() {
return (
<Container>
<Header></Header>
<Content style={{padding:20}}>
<Text style={{fontSize: 30, textAlign:'center', marginVertical:30,}}>Food Decider</Text>
<Item floatingLabel>
<Label>Add Item</Label>
<Input
onChangeText={(text) => this.setState({userdata:text})}
/>
</Item>
<Button block success style={{marginTop: 20,}}
onPress={this.onSubmit.bind(this)}
>
<Text>Add Item</Text>
</Button>
<FlatList
data = {this.state.items}
renderItem={({item}) => <Text style={styles.item}>{item.key}</Text>}
/>
</Content>
</Container>
);
}
onSubmit(){
this.state.items.push({key:this.state.userdata});
alert(JSON.stringify(this.state.items));
}
Thanks.
You need to use prop legacyImplementation=true in FlatList so that it does the real time changes to the FlatList.
Use:
<FlatList legacyImplementation=true />
first of all in you onSubmit function you didn't set the state just push a value
onSubmit(){
this.state.items.push({key:this.state.userdata});
alert(JSON.stringify(this.state.items));
}
whereas it should be something like this
onSubmit(){
let newState = this.state.items;
newState.push({key:this.state.userdata});
this.setState({items:newState});
alert(JSON.stringify(this.state.items));
}
and also bind your onSubmit function in the constructor like this
constructor(props){
super(props);
this.state = {items:[{key:'Pasta'},{key:'Pizza'}],userdata:''}
this.onSubmit = this.onSubmit.bind(this);
}
In Flat list there is also one more option
"extraData={this.state.metaData}"
you can use this to reset/reload the FlatList on your action complete ,you can use like this:
constructor(props){
super(props);
this.state={
metaData:false,
}
}
<FlatList
data = {this.state.items}
renderItem={({item}) => <Text style={styles.item}>{item.key}</Text>}
extraData={this.state.metaData}
/>
after button click you can use this
onSubmit(){
let {metaTAbBarData}=this.state
this.state.items.push({key:this.state.userdata});
this.setState({metaData:!metaData})
}
it will reload when you click on submit button
it will help you , its help me
onSubmit(){
/*
* FlatList is a PureComponent which means that it will not re-render
* if props remain shallow-equal So, We are Cloning the items array to
* clonedArray, So that the reference to this.state.items will change.
* Means this.state.items === clonedArray will give false value.
*/
let clonedArray = this.state.items.slice();
clonedArray.push({key:this.state.userdata});
this.setState({items: clonedArray});
}
Related
I am doing a loan calculation app and i run into the trouble since i am new to react native and previously i have been manipulating the DOM using querySelector or getElementById functions. However this does not work in react, and i am using state to store the value from the user, but i just can't seem to get it right, What am i doing wrong?
I've inserted the calculation element that is later rendered in app.js. All elements are showing up with no error, but the problem is to get user input data and then be able to use that data and do calculations.
Here is my Class
class LanKalkylElement extends React.Component {
constructor(props) {
super(props);
this.state = {
loanAmount: 20000,
loanInterest: 2.5,
loanYear: 10,
};
}
changeAmount(loanAmount) {
this.setState(() => {
return {
loanAmount: parseFloat(loanAmount),
};
});
}
changeInterest(loanInterest) {
this.setState(() => {
return {
loanInterest: parseFloat(loanInterest),
};
});
}
changeYear(loanYear) {
this.setState(() => {
return {
loanYear: parseFloat(loanYear),
};
});
}
calcButton() {
Alert.alert(this.props.loanAmount);
}
buttonHomeFunc() {
this.props.navigation.navigate('Start');
}
render() {
const {loanAmount, loanInterest, loanYear} = this.state;
return(
<View style={styles.contentStyle}>
<Text style={styles.text}> Lånebelopp </Text>
<TextInput style={styles.numericInput}
onBlur={Keyboard.dismiss}
keyboardType={'numeric'}
value={loanAmount}
onValueChange={this.changeAmount.bind(this)} />
<Text style={styles.text}> Ränta </Text>
<TextInput style={styles.numericInput}
onBlur={Keyboard.dismiss}
keyboardType={'numeric'}
value={loanInterest}
onValueChange={this.changeInterest.bind(this)} />
<Text style={styles.text}> Antal år: {String(loanYear)}</Text>
<Slider step={1}
maximumValue={15}
value={loanYear}
onValueChange={this.changeYear.bind(this)} />
<Button title='Kalkylera' onPress={() => this.calcButton()}/>
<Text style={styles.textResult}>Total summa att återbetala:</Text>
<Text style={styles.textResult}>varav räntekostnad:</Text>
<Button title='Tillbaka' onPress={() => this.buttonHomeFunc()}/>
</View>
)
}
}
export default withNavigation(LanKalkylElement);
When a user changes a value in a text input, onValueChange is called. You have bound this prop to functions that modify the state for this component.
This means the value in the text input will always match the value in the state. Therefore, if you need to access the value in a text input you would simply retrieve it from the state, like this:
const loanAmount = this.state.loanAmount;
doSomethingWithLoanAmount(loanAmount);
I'm currently struggling in making my FlatList applying the changes I do to it. What I am wanting right now is that when I click an item in my flatlist, that it highlights in a certain color. I followed an approach done by a guy but I am having the problem that to me is not working the update once I click.
I can see through console that all I am doing performs a modification but I think that I am missing some point with extraData parameter since it is not re-rendering with the backgroundColor that I would like to apply.
The code I have is as following, I know that the style I am applying is correct since if i substitute in the map styles.list per styles.selected, everything gets the background I would like to be applied to the elements I click.
So summarizing, the issue I think I have is that the flatlist is not re-rendering so it doesn't show the modifications I perform on it. Any idea of what I am doing wrong? Any tip?
render() {
const { students, studentsDataSource, loading, userProfile } = this.props.navigation.state.params.store;
this.state.dataSource = studentsDataSource._dataBlob.s1.map(item => {
item.isSelect = false;
item.selectedClass = styles.list;
return item;
})
const itemNumber = this.state.dataSource.filter(item => item.isSelect).length;
return (
<View style={styles.container}>
<Item rounded style={styles.searchBar}>
<Input placeholder='Group Name'/>
</Item>
<FlatList
style={{
flex: 1,
width: "100%",
}}
data={this.state.dataSource}
ItemSeparatorComponent={this.FlatListItemSeparator}
renderItem={ ({ item }) => (
<ListItem avatar style={[styles.list, item.selectedClass]}
onPress={() => this.selectItem(item)}>
<Left>
{!item.voteCount && <Avatar unseen={true} /> }
{!!item.voteCount > 0 && <Avatar />}
</Left>
<Body>
<Text>{item.name}</Text>
<Text note>{item.group}</Text>
</Body>
</ListItem>
)
}
listKey={item => item.key}
extraData={this.state}
/>
</View>
);
}
Here we can find the state and SelectItem functions:
constructor(props) {
super(props)
this.state = {
dataSource : [],
}
}
//FlatListItemSeparator = () => <View style={styles.line} />;
selectItem = data => {
//{console.log("inside SelectItem=", data)}
data.isSelect = !data.isSelect;
data.selectedClass = data.isSelect? styles.selected: styles.list;
const index = this.state.dataSource.findIndex( item => data.key === item.key);
this.state.dataSource[index] = data;
this.setState({
dataSource: this.state.dataSource,
});
console.log("This state has the changes:=",this.state.dataSource)
};
Well the main issue was that I was not using the .setState and instead I was doing assignations which killed the listeners.
I have a simple TextInput that I want to put a reference on in my render:
<View>
<TextInput ref={(component) => this._inputElement = component}>Input</TextInput>
{console.log(this._inputElement)}
<Button
onPress={this.addAddress}
title="Submit"
color="#841584"
/>
</View>
I want to then use that ref in a function above that is bound in my contructor:
constructor(props) {
super(props);
this.state = {
addresses: []
};
this.addAddress = this.addAddress.bind(this);
}
addAddress function:
addAddress(event, result) {
console.log("reference:", this._inputElement.value);
}
The console log in both the render and addAddress are always undefined.
I have looked around but no one seems to be having my problem, usually they have a typo or didn't bind the function they then want to call.
Why do I seem unable to have references?
Using State
Usually the way to use TextInput is to store the value in state.
Remember to initialize the address in your state as an empty string, otherwise having a null value for address could cause an error.
constructor(props) {
super(props)
this.state = {
....
address: ''
}
}
Then you could define your text input as follows
<TextInput
onChangeText={address => this.setState({address})}
value={this.state.address}
/>
Then in your addAddress
addAddress(event, result) {
console.log("reference:", this.state.address);
}
Using Refs
Alternatively you could use ._lastNativeText to access it from the reference
<TextInput
ref={ref => { this._inputElement = ref }}>
Input
</TextInput>
then in your addAddress
addAddress(event, result) {
// I always check to make sure that the ref exists
if (this._inputElement) {
console.log("reference:", this._inputElement._lastNativeText);
}
}
I wouldn't recommend the second method as you are accessing private methods that could be liable to change in a future release.
Textinput self-encloses
<View>
<TextInput ref={ref=> (this._inputElement = ref)}/>
<Button
onPress={this.addAddress}
title="Submit"
color="#841584"
/>
</View>
addAddress(event, result) {
console.log("reference:", this._inputElement._lastNativeText); //this get's the value, otherwise it's undefined
}
This snippet works properly in react native and react native web:
const txtRef = useRef(null)
return(
<TextInput
ref={txtRef}
onChangeText={text => txtRef.current.value = text}
/>
<Button
title='log and reset'
onPress={() => {
console.log(txtRef.current.value)
txtRef.current.clear()
txtRef.current.value = ''
}}
/>
)
`
I'm using react native text field component how can i remove bottom underline in textfield
this is my code
i followed this link: https://github.com/n4kz/react-native-material-textfield
constructor(props) {
super(props);
this.state = {
userName:'',
password:''
}
}
componentWillMount() {
}
componentDidMount(){
}
render() {
//let { userName } = this.state;
let { password } = this.state;
return (
<View style={{flex:1,justifyContent:'center'}}>
<View style={{flex:0.2,justifyContent:'center',flexDirection:'row'}}>
<View style={{flex:12}}></View>
<View style={{flex:76,borderWidth:1,borderColor:'black',borderRadius:5,marginBottom:13.7}}>
<TextField style={{ color: 'black',borderColor:'transparent'}}
label='Phone number'
textColor={'black'}
value={this.state.userName}
labelHeight={40}
labelPadding={8}
padding={10}
Bottom padding= {10}
Top padding={4}
//width={50}
//borderColor={'black'}
// textFocusColor={'orange'}
//underlineColorAndroid='transparent'
baseColor={"black"}
labelHeight={32}
blurOnSubmit={true}
//characterRestriction={10}
onChangeText={(data) => this.setState({ userName: data })}
/>
</View>
)
}
You can try underlineColorAndroid='rgba(0,0,0,0)'
Hope it helps
Other TextInput properties will also work
Ref: https://github.com/n4kz/react-native-material-textfield
React native material text field component (<TextField />) can also use all of the properties from text input component (<TextInput />). So, you can remove the underline border using underlineColorAndroid props. Set this prop to be transparent.
<TextField underlineColorAndroid="transparent" />
Try this: lineWidth={0} if you want to hide the default underline and if you want to hide the line after which appears after click try this: activeLineWidth={0}.
Fine, after using this library I end up with this solution:
You can use one of the props of react-native-material-textfield activeLineWidth with 0 as an argument.
underlineColor="transparent"
I got a response from API which i then parse and display some features on the screen using nativebase.io cardlist. When all the results are shown i want each card be clickable and each click leading to the next screen of details depending on a particular card's content. However, when the cardlist is rendered for some reason EVERY card is being clicked without the user interaction. So i'm looking for the solution which would allow a card click only when i touch any particular card.
class Results extends Component{
constructor(props){
super(props);
this.state = {
data: this.props.results
}
}
renderRow(item){
const bars = [ require('../assets/bar0.png'),
require('../assets/bar1.png'),
require('../assets/bar2.png'),
require('../assets/bar3.png')]
var bar = item.weight === -1 ? bars[0] : bars[item.weight]
return (
<CardItem button onPress={console.log("Pressed")} style={{width: 400}}>
<Thumbnail source={bar}/>
<Text>{item.label}</Text>
<Text note style={{textDecorationLine: 'line-through'}}>{item.excluded}</Text>
</CardItem>
)
}
render(){
console.log(this.state.data)
return (
<Container>
<Header>
<Title>symptoma</Title>
</Header>
<Content>
<Card dataArray={this.state.data}
renderRow={(item) =>
this.renderRow(item)
}>
</Card>
</Content>
</Container>
);
}
}
export default Results
replace
onPress={console.log("Pressed")}
with
onPress={() => console.log("Pressed")}