0

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 ?

1
  • Did you try to filter themes: {themes.filter(theme => theme.toLowerCase().includes(input.trim().toLowerCase()) => (Template...)} Commented Sep 6, 2022 at 12:53

2 Answers 2

2

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>
        ))}

Sign up to request clarification or add additional context in comments.

Comments

1

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>

1 Comment

That looks interesting ill give that a try, thanks

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.