Я получил ответ от проблемы с кодированием, которую я сделал, что одна из причин, по которой они меня не приняли, заключалась в том, что большая часть логики c была распространена в моем компоненте, где она могла быть в пользовательском хуке, и я мог также использовать useReducer вместо usestate.
Как вы можете видеть в моем компоненте, у меня есть два метода, один handleSearchByNameChange
обрабатывает, когда пользователь вводит данные, и проверяет, сопоставляет ли он какой-либо символ (символы загружаются при загрузке )
Другой handleClick
обрабатывает, когда пользователь отправляет форму, делает запрос ajax и устанавливает характер, возвращаемый вызовом ajax.
Теперь я пытаюсь понять, как бы я превратил их в пользовательские хуки.
Я попытался создать этот пользовательский хук для метода, который обрабатывает поиск по тексту handleSearchByNameChange
:
const useSearchByName = (query, characters) => {
const [selectedCharacterId, setSelectedCharacterId] = useState('');
const [searchQuery, setSearchQuery] = useState('');
const matchedCharacter = characters.find(character => character.name.toLowerCase() === query.toLowerCase().trim());
if (matchedCharacter) setSelectedCharacterId(matchedCharacter.id);
setSearchQuery(query);
return [selectedCharacterId, searchQuery]
}
Возвращает selectedCharacterId и searchQuery ...
Если вы посмотрите на оригинальный манипулятор handleSearchByNameChange
ниже, вы увидите, что внутри него есть логика c для отключение кнопки, которую я удалил в хуке, так как я думаю, что ее можно добавить в собственную хук, так как она не имеет ничего общего с функцией поиска по имени.
Но теперь, как мне это использовать в контекст моего компонента? Если я передаю этот пользовательский хук как реквизит, он просто возвращает selectedCharacterId и searchQuery в ничто ... или я не должен ничего возвращать из него и просто установить состояние selectedCharacterId и searchQuery? это кажется странным.
Как вы видите, я очень растерялся.
Любая помощь очень аппетитна.
Это весь мой компонент:
const CharacterSelectorContainer = () => {
const [characters, error] = useLoadCharacters()
const [selectedCharacterId, setSelectedCharacterId] = useState('');
const [searchQuery, setSearchQuery] = useState('');
const [searchBtnIsEnabled, setSearchBtnIsEnabled] = useState(true);
const [character, setCharacter] = useState(null)
const handleSearchByNameChange = query => {
const matchedCharacter = characters.find(character => character.name.toLowerCase() === query.toLowerCase().trim());
if (matchedCharacter) setSelectedCharacterId(matchedCharacter.id);
setSearchQuery(query);
if (query.length > 0 && !matchedCharacter) {
setSearchBtnIsEnabled(false)
} else if (query.length > 0 && matchedCharacter) {
setSearchBtnIsEnabled(true)
} else {
setSearchBtnIsEnabled(true)
setSelectedCharacterId(selectedCharacterId)
}
}
const handleClick = async e => {
e.preventDefault();
if (selectedCharacterId) {
setCharacter(null)
try {
const receivedCharacter = await getCharacter(selectedCharacterId)
const similarCharacters = characters
.filter(char => char.species === receivedCharacter.species)
.map(item => item['name'])
setCharacter({
...receivedCharacter,
similarCharacters,
})
} catch {
console.log('Ooops there was an error fetching character.')
}
}
}
return !characters
? <p data-testid="character-selector-error" className="tc b f1">{error}</p>
: <CharacterSelector
handleClick={handleClick}
searchQuery={searchQuery}
selectedCharacterId={selectedCharacterId}
characters={characters}
searchBtnIsEnabled={searchBtnIsEnabled}
error={error}
character={character}
setSelectedCharacterId={setSelectedCharacterId}
handleSearchByNameChange={handleSearchByNameChange}
/>
}
export default CharacterSelectorContainer