Sunday, May 19, 2024
 Popular · Latest · Hot · Upcoming
69
rated 0 times [  72] [ 3]  / answers: 1 / hits: 6416  / 5 Years ago, sat, november 9, 2019, 12:00:00

I have run into a weird bug with my search input component where it loses focus on every keypress and can't figure out why.



const App = () => {
let [characters, setCharacters] = useState([]);
let [filteredCharacters, setFilteredCharacters] = useState([]);
// more state
let [search, setSearch] = useState();

useEffect(() => {
setIsLoading(true);
axios
.get(`https://swapi.co/api/people/?page=${pageNumber}`)
.then(res => {
console.log(res.data.results);
setCharacters(res.data.results);
setFilteredCharacters(res.data.results);
})
.catch(err => console.error(err))
.then(() => {
setIsLoading(false);
});
}, [pageNumber]);

function updatePage(e) {
// update page
}

function handleSearch(e) {
setSearch(e.target.value);
const filtered = characters.filter(character => {
if (character.name.toLocaleLowerCase().indexOf(e.target.value) !== -1) {
return character;
}
});
setFilteredCharacters(filtered);
}
function SearchBar() {
return (
<React.Fragment>
<StyledInput
type=text
id=search
value={search}
placeholder=Search by name...
onChange={e => handleSearch(e)}
/>
</React.Fragment>
);
}

return (
<React.Fragment>
<GlobalStyles />
<div className=App>
<Heading>React Wars!</Heading>
<SearchBar />
<Pagination handleClick={updatePage} />
{!isLoading && Object.entries(filteredCharacters).length ? (
<CharacterList characters={filteredCharacters} />
) : (
<LoadingBar />
)}
</div>
</React.Fragment>
);
};


I'm also getting a Line 65:50: Expected to return a value at the end of arrow function array-callback-return for the characters.filter() line so I don't know if that has to do with it.



If it helps, the deployed app with the bug can be seen here --> https://mundane-vacation.surge.sh


More From » reactjs

 Answers
0

You have a problem with focus because your component SearchBar is declared inside App component and it is recreated on each rendering. You need to move SearchBar out of App or just move StyledInput on the place of SearchBar. If you choose the first way, I recommend you remove React.Fragment from SearchBar, because it has only one rendered child:



function SearchBar(props) {
return (
<StyledInput
type=text
id=search
value={props.value}
placeholder=Search by name...
onChange={props.onChange}
/>
);
}


And in App:



<SearchBar onChange={handleSearch} value={search} />


To fix your warning, you need always return a boolean value inside the filter function. Now you return nothing (i.e. undefined) in case if the character does not pass the condition. So change your filter function like this:



const filtered = characters.filter(character => {
return character.name.toLocaleLowerCase().indexOf(e.target.value) !== -1
});

[#5666] Thursday, November 7, 2019, 5 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
albert

Total Points: 652
Total Questions: 105
Total Answers: 108

Location: Pitcairn Islands
Member since Fri, Oct 15, 2021
3 Years ago
;