I am new to working with React.js, trying to make a filter, but I ran into a number of problems, I will be grateful if you can tell me how to do it. There is a main component of Speakers.js in which I get json and then send it to the internal List and Filter components. I list the entire list of speakers in the List (which comes in Json). In Filter, when you enter the name or address field and then when you click on the search button, a search should occur. enter image description here

Speakers.js

import React, {Component} from 'react'; import Filters from './Filters'; import List from './List'; class Speakers extends Component { constructor(props) { super(props); this.state = { isLoading: false, items: [] } } componentDidMount() { this.setState({isLoading: true}); fetch("https://randomapi.com/api/6de6abfedb24f889e0b5f675edc50deb?fmt=raw&sole") .then(res => res.json()) .then( (result) => { this.setState({ items: result, isLoading: false }); console.log(result); } ) .catch(error => this.setState({ error, isLoading: false })); } render() { return ( <div className="speakers"> <div className="container-fluid"> <Filters getItems={this.state} /> <List getItems={this.state} /> </div> </div> ); } } export default Speakers; 

List.js

 import React, {Component} from 'react'; class List extends Component { render() { const {items, isLoading} = this.props.getItems; if (isLoading) { return <p>Loading ...</p>; } return ( <div className="speakers__list"> <div className="row"> {items.map((item, index) => ( <div className="col-md-3" key={index}> <div className="card form-group shadow"> <div className="card-body text-center"> <h5 className="card-title">{item.first} {item.last}</h5> <p>{item.email}</p> <p>{item.address}</p> <p>{item.balance}</p> <p>{item.created}</p> </div> </div> </div> ))} </div> </div> ) } } export default List; 

Filters.js

 import React, {Component} from 'react'; class Filters extends Component { render() { return ( <div className="filters"> <div className="alert shadow"> <form> <div className="container-fluid"> <div className="row"> <div className="col-md-5"> <label>Name/Surname</label> <input type="text" className="form-control" /> </div> <div className="col-md-5"> <label>Address</label> <input type="text" className="form-control"/> </div> <div className="col-md-2 align-self-center text-center"> <button className="btn btn-primary">Search</button> </div> </div> </div> </form> </div> </div> ); } } export default Filters; 

    1 answer 1

    You need to set up data exchange between two components ( List and Filter ), which are connected only by the parent ( Speakers ). The easiest way to link them is through it:

    We get the name and address field in a stey. And handlers:

     _handleAddressChange = value => this.setState({address: value}) _handleNameChange = value => this.setState({name: value}) 

    Next, we forward all of this to our Filter :

     <Filters name={this.state.name} address={this.state.address} onNameChange={this._handleAdressChange} onAddressChange={this._handleAddressChange} /> 

    We put everything in its place in it, so that when we write to the input, its data will fall into the state of the Speakers . And we filter the data as we need:

     <List getItems={this.state.items.filter(({name, address}) => this.state.name === name || this.state.address === address)} /> 

    PS Such actions are often done through redux or mobx

    • tell me what you need to do in the List which changes in the function {items.map ((item, index) => ... now just an error occurs TypeError: Cannot read property 'map' of undefined - Dima Vleskov
    • Here is such a mistake joxi.ru/nAypZqPHYvW072 - Dima Vleskov
    • one
      Try this {items && items.map ((item, index) => ...} If the data comes from the server, then there is nothing in the items until the server sends a response. - Bogdan Ivanchenko