Home > database >  How to filter an array of strings with an input
How to filter an array of strings with an input

Time:09-07

Hi im using react and have an array of strings

const themes = [
  'light',
  'dark',
  'cupcake',
  'bumblebee',
  'emerald',
  'corporate',
  'synthwave',
  'retro',
  'cyberpunk',
  'valentine',
  'halloween',
  'garden',
  'forest',
  'aqua',
  'lofi',
  'pastel',
  'fantasy',
  'wireframe',
  'black',
  'luxury',
  'dracula',
  'cmyk',
  'autumn',
  'business',
  'acid',
  'lemonade',
  'night',
  'coffee',
  'winter',
]

What i'm doing is mapping over them like this

{themes.map((Theme) => (
          <li
            className={`${theme === Theme && 'btn-primary'} ${
              input.includes(Theme) && "btn-primary"
            }`}
            key={Theme}
            onClick={() => setTheme(`${Theme}`)}
          >
            <label>{Theme}</label>
          </li>
        ))}

I have an input at the top with state

  const [input, setInput] = useState('')
  <input
    type="text"
    placeholder="Type here"
    className="w-full max-w-xs py-3 mb-3 input input-bordered"
    value={input}
    onChange={(e) => setInput(e.target.value)}
        />

I tried to use the regular filter method but i can't find a way to just simply filter an array of strings and if the input matches or contains the letters of a single theme to just show that ?

CodePudding user response:

You need to filter the items before map.

{themes.filter(t => t.toLowerCase().includes(input.toLowerCase())).map((Theme) => (
          <li
            className={`${theme === Theme && 'btn-primary'} ${
              input.includes(Theme) && "btn-primary"
            }`}
            key={Theme}
            onClick={() => setTheme(`${Theme}`)}
          >
            <label>{Theme}</label>
          </li>
        ))}

CodePudding user response:

When your input changes it will re-render the component. When that happens you can call a function that filters out any theme that startsWith (or includes) that value.

const { useState } = React;

function Example({ themeData }) {

  const [ themes, setThemes ] = useState(themeData);
  const [ input, setInput ] = useState('');

  // Accept the input, and return a filtered array
  function filterThemes(input) {
    return themes.filter(theme => {
      return theme.startsWith(input);
    });
  }

 // Set the input 
 function handleInput(e) {
    setInput(e.target.value);
  }

  return (
    <main>
      <label for="themeInput">
        Filter themes:
        <input
          value={input}
          id="themeInput"
          onInput={handleInput}
        />
      </label>
      <ul>
        {filterThemes(input).map(theme => {
          return <li>{theme}</li>;
        })}
      </ul>
    </main>
  );

}

const themes=["light","dark","cupcake","bumblebee","emerald","corporate","synthwave","retro","cyberpunk","valentine","halloween","garden","forest","aqua","lofi","pastel","fantasy","wireframe","black","luxury","dracula","cmyk","autumn","business","acid","lemonade","night","coffee","winter"];

ReactDOM.render(
  <Example themeData={themes} />,
  document.getElementById('react')
);
input { margin-left: 0.25em; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="react"></div>

  • Related