Wahidul Alam
Wahidul Alam

Reputation: 1253

React Native Search filter not working properly

I am trying to implement react native search filter. I have my data array on the parent screen and I applied the search filter on the parent file and passed the filtered data array as props to the child screen. But no filter is happening. I am confused or no clue what wrong i am doing. I have the following codes:

ParentScreen.js

import SearchInput, { createFilter } from 'react-native-search-filter';
...
const KEYS_TO_FILTERS = ['title']

export default class ProductScreen extends Component {
    constructor(props) {
        super(props)
        this.state = {
            items: API,
            searchTerm: '',
        }
    }

    searchUpdated(term) {
        this.setState({ searchTerm: term })
    }

    render() {

        const filteredItems = this.state.items.filter(createFilter(this.state.searchTerm, KEYS_TO_FILTERS))

        let cardGridWithBodyProps = {
            navigation: this.props.navigation,
            api: filteredItems,
            gridNumber: 2,
        }

        return (
            <Container>
                <ScrollView showsVerticalScrollIndicator={false}>
                    <View>
                        <Header>
                            <SearchInput 
                            onChangeText={(term) => { this.searchUpdated(term) }}
                            placeholder="Search"
                            />
                        </Header>
                    </View>
                    <View>
                        <CardGridWithBody {...cardGridWithBodyProps} />
                    </View>
                </ScrollView>
            </Container>
        )
    }
}

ChildScreen.js

export default class CardGridWithBody extends Component {
    constructor(props) {
        super(props)
        this.state = {
            items: this.props.api
        }
    }

    renderGrid(gridArray) {
        return gridArray.map((row, rowIndex) => (
            <Row key={rowIndex}>
                {row.map((col, colIndex) => (this.renderColumn(col, rowIndex,colIndex)))}
            </Row>
        ));
    }

    renderColumn(colItem, rowIndex, colIndex) {
        return (
            <Col  key={colIndex}>
                <Text>{colItem.title}</Text>       
            </Col>
        )
    }

    renderContent() {
        let gridArray = this.state.items
        return this.renderGrid(gridArray)
    }

    render() {
        return (
            this.renderContent()
        )
    }
}

Upvotes: 1

Views: 854

Answers (2)

Kamal Pandey
Kamal Pandey

Reputation: 1596

In parent screen convert

 searchUpdated(term) {
   this.setState({ searchTerm: term })
 }

to

 searchUpdated = term => {
      this.setState({ searchTerm: term })
    }

and in your child component you can do

static getDerivedStateFromProps(nextProps, prevState) {
      if (nextProps.api !== prevState.api) {
        return { api: nextProps.api };
      }
      return null;
    }

    componentDidUpdate(prevProps, prevState) {
      if (
        this.state.items !==
        prevState.items
      ) {
        this.setState({ items: api });
      }
    }

Upvotes: 0

Junius L
Junius L

Reputation: 16152

Instead of saving the data in state, access it directly from props. If you save it in state, you'll need to update it manually using lifecycle methods such as shouldComponentUpdate or getDerivedStateFromProps

renderContent = () => {
  let gridArray = this.props.api;
  return this.renderGrid(gridArray);
}

Upvotes: 1

Related Questions