Search code examples
reactjsjsxreact-component

Update list when input value changes


I have three components: the main component, input component and the list component. When I start typing in the input field. I want the list to update with all matching results of what I typed. I have the timeout function and it works. It is confusing me because the input and list components aren't children or parents of each other.

But how would I connect the components to work together for that?

Main component:

import React from 'react';
import ReactDOM from 'react-dom';
import Header from './Components/Header/Header'
import Input from './Components/Input/Input'
import List from './Components/List/List'
import './index.css';


ReactDOM.render(
  <React.StrictMode>
    <Header title="Contacts"/>
    <Input type="text" />
    <List />
  </React.StrictMode>,
  document.getElementById('root')
);

List Component:

import { useState, useEffect } from 'react'
import ListItem from './ListItem'
import fetchData from '../../API/api'

import '../../index.css'

function List(params){
    const API_LINK = 'https://teacode-recruitment-challenge.s3.eu-central-1.amazonaws.com/users.json';
    const [ data , fetchedData ] = useState([]);

    const options = {
        startCallback: (data) => {return fetchedData(data)}
    }
    
    useEffect( () => {
        fetchData(API_LINK).then((data) => fetchedData(data));
    }, []) 

    return (
        <ul className="list">{data.map(
                (fetchedData) => {return <ListItem key={fetchedData.id} avatarImage={fetchedData.avatar}
                personName={fetchedData.first_name} personSurname={fetchedData.last_name} personMail={fetchedData.email}
                />}
                )}
        </ul>
    )
}

export default List;

Input Component:

import { useRef } from 'react';
import { BsSearch } from 'react-icons/bs'
import '../../index.css'

function Input(type){
    const focusInput = useRef(null)

    function makeFocus(){
        focusInput.current.focus();
    }

    function onInputChange(e){
        
        setTimeout(() => {
            console.log(e.target.value)
        }, 2500)
        
    }

    return (
        <div className="searchBar-box" onClick={makeFocus}>
            <i className="searchBar-box__icon"><BsSearch /></i>
            <input className="searchBar-box__input" ref={focusInput} type={type} onChange={onInputChange}></input>
        </div>
    )
}

export default Input;

Solution

  • you can level up input value in component what contain input and list

    for example:

    function ListWithFilter() {
       const [searchWord, setSearchWord] = useState('');
    
      return <>
        <Input value={searchWord} setValue={setSeachWord} />
        <List searchWord={searchWord} />
      </>
    }
    
    function Input (props) {
     return <input value={props.value} onChange={(e) => props.setValue(e.target.value)} />
    }
    
    function List(props) {
        const listData = ['hello', 'world', 'hello wold'];
        
        const filtered = listData.filter(s => s.includes(props.searchWord));
      
        return <div>{filtered.map(s => div)}</div>
    }