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>