2

I'm a beginner in React Native ans struggling with adding Input (Search bars) into a list by clicking a button. Here's my code:

import React, { useState } from "react";
import {
    View,
    Text,
    Button,
    FlatList
} from 'react-native'
import InputDemo from '../components/InputDemo'

const INCREMENT = 1;

class AddInputDemo extends React.Component{
    constructor(props){
        super(props);
        this.state={
            counter: 0,
            numOfInput: [0]
        }
        this.addInput = this.addInput.bind(this)
    }

    addInput(){
        this.setState((state) => ({
            counter: state.counter + INCREMENT,
            numOfInput: [...state.numOfInput, state.counter]
        }))

        console.log(this.state.counter);
        console.log(this.state.numOfInput);



    }
    render(){
        return(
            <View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
                <FlatList
                    data={this.state.numOfInput}
                    keyExtractor={(item, index) => item.id}
                    renderItem={itemData => {
                        <InputDemo/>
                    }}
                />
                <Button title='Add a location' onPress={this.addInput} />

            </View>
        );
    }

}

export default AddInputDemo;

Here's the InputDemo file:

import * as React from 'react'
import {
    View,
    Text,
    TextInput,
    Button
} from 'react-native'

const InputDemo = props => {
    return(
        <View style={{borderColor: 'black', borderWidth: 1}}>
            <TextInput
                placeholder='Search'
            />
        </View>
    )
}

export default InputDemo;

It's weird since I use this same logic with state in Functional Component. It works. But when applying to a Class Component, it does not show anything when I click that button.

THANKS FOR ANY HELP !!!

EDIT I tried to use extraData:

<FlatList
                    extraData={this.state.numOfInput}
                    keyExtractor={(item, index) => item.id}
                    renderItem={itemData => {
                        <InputDemo
                            id={itemData.item.id}
                        />
                    }}
                />

And created an id for each InputDemo:

const InputDemo = props => {
    return(
        <View key={props.id} style={{borderColor: 'black', borderWidth: 1}}>
            <TextInput
                placeholder='Search'
            />
        </View>
    )
}

But it still does not work Please help !!!

3 Answers 3

1

FlatList data attribute takes prop as Array. Documentation is your bestfriend. Everything goes more or less like below, not tested but closer to what you want, I hope.

import React, { useState } from "react";
import {
    View,
    Text,
    Button,
    FlatList
} from 'react-native'
import InputDemo from '../components/InputDemo'

const INCREMENT = 1;


class AddInputDemo extends React.Component{
    constructor(props){
        super(props);
        this.state={
            counter: 0,
            numOfInput: [0],
            item:'',
            searchArray:[],

        }
        this.addInput = this.addInput.bind(this)
    }


    addInput(){

        this.setState((state) => ({
            counter: state.counter +=1,
            searchArray:[...this.state.searchArray, this.state.item] //appends search item to search array
            numOfInput: [...state.numOfInput, state.counter]  //don't know why you need this
        }))

    }
    render(){
        return(
            <View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>

           <InputDemo search={(searchItem)=>this.setState({item:searchItem})}/>     
           <FlatList
                    data={this.state.searchArray}
                    keyExtractor={(item, index) => item.id}
                    renderItem={itemData => {
                        <Text>{itemData}</Text>
                    }}
                />
                <Button title='Add a location' onPress={this.addInput} />

            </View>
        );
    }

}

export default AddInputDemo;

And Input Demo

import * as React from 'react'
import {
    View,
     TextInput
} from 'react-native'

const InputDemo = props => {


   const onChangeText = (item) => {
         props.search(item);  //add search item to state of "class AddInputDemo" using props
      }
    return(
        <View style={{borderColor: 'black', borderWidth: 1}}>
            <TextInput
                placeholder='Search'
                onChangeText={text => onChangeText(text)}
            />
        </View>
    )
}

export default InputDemo;
Sign up to request clarification or add additional context in comments.

Comments

1

EDIT 2 Hi guys, I know where the error is now. It's not about the data or extraData. The solution is we have to wrap around the <InputDemo/> with a return statement. It works well then. Thank you all for the helpful answers.

Comments

1

You should pass extraData

A marker property for telling the list to re-render (since it implements PureComponent). If any of your renderItem, Header, Footer, etc. functions depend on anything outside of the data prop, stick it here and treat it immutably.

<FlatList
    data={this.state.numOfInput}
    extraData={counter}
    keyExtractor={(item, index) => item.id}
    renderItem={itemData => (
        <InputDemo/>
    )}
/>

Edit:

You also have a huge problem, your data don't have .id prop and keyExtractor probably isn't working.

You could change it to

keyExtractor={(item, index) => index.toString()}

But this still isn't good, try adding unique id prop to each item.

2 Comments

you mean replace data with extraData ? Since, InputDemo doesn't have anything extra props. It's just a <TextInput/> component
Thanks for the edit. I've tried but it still doesn't work. I tried to pass a key for the view in InputDemo. And used: extraData={this.state.numOfInput}. The screen still shows nothing. Please help

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.