DEV Community

Discussion on: Let's build a search bar in React!

Collapse
 
nemethricsi profile image
Richard • Edited

Hi there,

Really liked your tutorial Tim! <3 I thought I try all of that with functional components and this is what I got (feel free to correct me - I'm kinda rookie in webdev). Seems working though!

Minor changes I made:

  • used functional components instead of class components. Therefore used React.useState() for storing variables in the state.

  • input element for adding new todo is a controlled component and handled also in the state. Found this approach more "react-ish".

  • for deleting a todo I also used filter() method - seems more handy for me.

  • some naming changes

App.js

// App.js

import React, { useState, Fragment } from "react";
import List from "./List";

const App = () => {
  const [userInput, setUserInput] = useState("");
  const [list, setList] = useState([
    "walk the dog",
    "buy the milk",
    "learn some code"
  ]);

  // userinput is controlled by the App component
  const handleChange = e => {
    setUserInput(e.target.value);
  };

  const addItem = e => {
    if (userInput !== "") {
      setList([...list, userInput]);
      setUserInput("");
    }
  };

  const removeItem = item => {
    const updatedList = list.filter(listItem => listItem !== item);
    setList(updatedList);
  };

  return (
    <Fragment>
      <List list={list} removeItem={removeItem} />
      <hr />
      <form>
        <input
          placeholder="Something that needs to be done..."
          value={userInput}
          onChange={handleChange}
        />
        <button type="button" onClick={addItem}>
          {'Add Item'}
        </button>
      </form>
    </Fragment>
  );
}

export default App;

List component:

// List.js

import React, { useState, useEffect, Fragment } from "react";

const List = ({ list, removeItem }) => {
  const [filtered, setFiltered] = useState([]);

  useEffect(() => {
    setFiltered(list);
  }, [list]);

  const handleChange = e => {
    let currentList = [];
    let newList = [];

    if (e.target.value !== "") {
      currentList = list;
      newList = currentList.filter(item => {
        const lc = item.toLowerCase();
        const filter = e.target.value.toLowerCase();
        return lc.includes(filter);
      });
    } else {
      newList = list;
    }
    setFiltered(newList);
  };

  return (
    <Fragment>
      <input 
        type="text" 
        placeholder="Search..." 
        onChange={handleChange} 
      />
      <ul>
        {filtered.map((todo, i) => (
          <li key={`${todo}-${i}`}>
            {todo} &nbsp;
            <span onClick={() => removeItem(todo)}>x</span>
          </li>
        ))}
      </ul>
    </Fragment>
  );
};

export default List;

default create-react-app index.js...

// index.js

import React from "react";
import ReactDOM from "react-dom";

import App from "./App";

const rootElement = document.getElementById("root");
ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  rootElement
);