Search code examples
javascriptreactjsreact-component

How to make React App to filter only one item


Following a course by Andrei Neagoie on Udemy, I'm making this robots app that displays and filters data gotten from an API. I've customized it a little bit and added a carousel feature, but now, when I hit the searchbox and try to filter it displays more than one item. I want it displaying only one item, how can I do this?
This is the problem I'm having: https://i.sstatic.net/2upC2.jpg

App.js

import React, { Component } from 'react'
//import CardList from './components/CardList';
import SearchBox from './components/SearchBox';
import Splider from './components/Splider';

class App extends Component {
  constructor(){
    super()
    this.state = {
      robots: [],
      searchField: ''
    }
  }

  componentDidMount(){
    fetch('https://jsonplaceholder.typicode.com/users')
      .then(res => {
        return res.json();
      })
      .then(users => {
        this.setState({
          robots: users
        });
      });
    
  }

  onSearchChange = (e) => {
    this.setState({
      searchField: e.target.value 
    });
  }

  render() {
    const filtered = this.state.robots.filter(robot => {
      return robot.name.toLowerCase().includes(this.state.searchField.toLowerCase());
    });

    // Main Render
    return (
      <div className="App tc">
        <h1>RoboBros!</h1>
        <SearchBox searchChange={this.onSearchChange}/>
        <Splider robots={filtered}/>
        {/* <CardList robots={filtered}/> */}
      </div>
    )
  }
}

export default App

SearchBox.js

import React from 'react'
import '../index.css'

const SearchBox = ({ searchChange, searchField }) => {
    return (
        <div className="search-div">
            <input className="search-box center" type="search" placeholder="Search Robots" onChange={searchChange}/>
            <button className="search-btn">Search</button>
        </div>
    )
}

export default SearchBox;

Cards.js(Individual card items)

import React from 'react'
import '../styles/Cards.css';

const Cards = ({ name, id, email }) => {
    return (
        <div className="cards-wrapper dib br3 pa3 ma2 grow pointer">
            <img className="cent" src={`https://robohash.org/${id}?set=set3`} alt="robots"/>
            <div className="text">
                <h3>{name}</h3>
                <h4>{email}</h4>
            </div>
        </div>  
    )
}

export default Cards;

CardList.js

import React from 'react';
import Cards from './Cards';

const CardList = ({robots}) => {
    const cardComponent = robots.map((robot, i) => {
        return <Cards key={i} id={robots[i].id} name={robots[i].name} email={robots[i].email}/>;
    })

    return(
        <div>
            {cardComponent}
        </div>
    );
}

export default CardList;

Splider.js(Component that holds the Carousel/Slider library)

import React from 'react';
import { Splide, SplideSlide } from '@splidejs/react-splide';
import '@splidejs/splide/dist/css/themes/splide-sea-green.min.css';
import '../styles/Cards.css';

const Splider = ({robots}) => {
    const cardSplide = robots.map((robot, i) => {
        return (
            <SplideSlide key={i} className="cards-wrapper dib br3 pa3 ma2">
                <img src={`https://robohash.org/${robots[i].id}?set=set3`} alt="robots"/>
                <h3>{robot.name}</h3>
                <h4>{robot.email}</h4>
            </SplideSlide>
        );
    });

    return(
        <Splide options={{
            rewind: true,
            width: '100%',
            gap: '1rem',
            perPage: 3,
            perMove: 1,
            focus: 'center',
            type: 'loop',
            easing: 'ease',
        }}>
            {cardSplide}
        </Splide>
    );
}

export default Splider;

Solution

  • The issue is with type: loop option:

    import React from "react";
    import { Splide, SplideSlide } from "@splidejs/react-splide";
    import "@splidejs/splide/dist/css/themes/splide-sea-green.min.css";
    import "../styles/Cards.css";
    
    const Splider = ({ robots }) => {
      return (
        <Splide
          options={{
            rewind: true,
            width: "100%",
            gap: "1rem",
            perPage: 3,
            perMove: 1,
            focus: "center",
            //type: "loop",
            easing: "ease"
          }}
        >
          {robots.map((robot, i) => {
            return (
              <SplideSlide key={robot.id} className="cards-wrapper dib br3 pa3 ma2">
                <img
                  src={`https://robohash.org/${robot.id}?set=set3`}
                  alt="robots"
                />
                <h3>{robot.name}</h3>
                <h4>{robot.email}</h4>
              </SplideSlide>
            );
          })}
        </Splide>
      );
    };
    
    export default Splider;
    
    

    This is the issue in splidejs project: https://github.com/Splidejs/splide/issues/145
    It shows as fixed, so probably you need to wait for react-splide to include the fix as well in it's latest version.