Я относительно новичок в ReactJS, и я пытаюсь реализовать небольшую форму, содержащую текстовое поле ввода и кнопку поиска. Я использую псевдоселектор: focus в поле ввода, поэтому, когда пользователь вводит информацию, он увеличивает ширину до 2000%, а когда элемент теряет фокус, он возвращается к ширине: 130%.
Проблема, с которой я сталкиваюсь, заключается в том, что когда я нажимаю кнопку поиска в первый раз, поле ввода сжимается до исходного положения, но оно не выполняет поиск, пока я не щелкну его во второй раз. Если я что-то набираю, а затем щелкаю где-нибудь еще, чтобы потерять фокус, это работает как шарм.
Вот мой код:
import React from 'react'
import Header from '../base/header'
import axios from 'axios'
import SearchResults from './searchResults'
import ReactCSSTransitionGroup from 'react-addons-css-transition-group';
import Radium from 'radium';
class Search extends React.Component {
constructor(props) {
super(props)
this.state = {
searchTerm: "",
searchResultsList: ""
}
this.handleChangeEvent = this.handleChangeEvent.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.handleCallback = this.handleCallback.bind(this);
}
handleCallback() {
console.info("calling handleSubmit");
}
handleSubmit() {
var that = this
event.preventDefault();
axios.post('http://localhost:3000/users/findusers', {
searchTerm: this.state.searchTerm
}).then(function (response) {
console.info("data sent");
that.setState({searchResultsList: response.data})
}).catch(function (error) {
console.info(error);
});
}
handleChangeEvent(e) {
this.setState({searchTerm: e.target.value}, () => {
console.info(this.state.searchTerm);
});
}
render() {
return (
<div>
<Header/>
<form onSubmit = {this.handleSubmit}>
<div>
<ReactCSSTransitionGroup
transitionName = "search-input"
transitionAppear = {true}
transitionAppearTimeout = {500}
transitionEnter = {false}
transitionLeave = {false}>
<input
type = "text"
style = {styles.inputStyle}
value = {this.state.searchTerm}
onChange = {this.handleChangeEvent}
placeholder = "Find Friends..."
/>
{/*<img onClick = {() => this.handleSubmit()} */}
<img src = "/icons/svg/magnifying-glass.svg"
alt = "Search" className = "searchIcon"
onClick = {() => this.handleCallback()}
/>
</ReactCSSTransitionGroup>
</div>
</form>
<div className = "container-fluid">
<div className = "row">
<div className = "col-md-3">left</div>
{/* Main Area */}
<div className = "col-md-6">
<SearchResults
searchResultsList = {this.state.searchResultsList}
/>
</div>
<div className = "col-md-3">right</div>
</div>
</div>
</div>
)
}
}
const styles = {
inputStyle: {
marginTop: 5,
marginLeft: 20,
width: 130,
WebkitTransition: 'width 0.4s easeInOut',
msTransition: 'width 0.4s easeInOut',
':focus': {
width: '2000%'
}
}
};
export default Radium(Search)
Изначально у меня был код в отдельном файле CSS, и я решил сделать его встроенным, чтобы посмотреть, есть ли разница. Я пробовал создавать разные функции, чтобы увидеть, есть ли разница, но все равно ведет себя одинаково.
Буду очень признателен за любую помощь!
Спасибо. Я подумал о том же и попробовал с backgroundColor: 'green', просто чтобы попробовать. Как width, так и backgroundColor работают, как только элемент получает фокус, но все еще вызывает проблему при нажатии кнопки поиска.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


По поводу изменения ширины при нажатии на лупу. Я считаю, что это потому, что свойство :focus находится на входе, а не в div, содержащем input и img.
Я бы рекомендовал использовать свойство :focus-within в родительском div. Вот пример div с обоими свойствами.
#div1:focus-within > input {
width: 300px;
}
#div2 > input:focus {
width: 300px;
}<div id = "div1">
<input type = "text"/>
<button>Search</button>
</div>
<div id = "div2">
<input type = "text"/>
<button>Search</button>
</div>Это должно решить проблему с фокусировкой.
Не знаю, почему ваше изображение с увеличительным стеклом работает так странно. При чтении кода кажется, что щелчок по изображению вызывает handleCallback(), который только регистрирует, а не отправляет.
Не уверен, что это поможет, но я бы рекомендовал использовать кнопку или элемент ввода для отправки. Кнопка будет иметь type = "submit" с изображением лупы в качестве дочернего элемента. Вход будет иметь type = "submit" value = "" и установить CSS background-image: на увеличительное стекло.
Потрясающие! Ваше решение отлично работает, я изменил свой CSS, как вы предложили, и вместо использования input type = "submit" я использовал элемент <button> и вложил свое изображение как дочерний элемент, содержащий атрибут onClick. Я искренне ценю вашу помощь, Марвин!
Уверены, что
width- хороший способ проверить фокусировку? Может, сborderColorсработает?