: проблемы с фокусом в React

Я относительно новичок в 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, и я решил сделать его встроенным, чтобы посмотреть, есть ли разница. Я пробовал создавать разные функции, чтобы увидеть, есть ли разница, но все равно ведет себя одинаково.

Буду очень признателен за любую помощь!

Уверены, что width - хороший способ проверить фокусировку? Может, с borderColor сработает?

Sulthan 03.06.2018 07:02

Спасибо. Я подумал о том же и попробовал с backgroundColor: 'green', просто чтобы попробовать. Как width, так и backgroundColor работают, как только элемент получает фокус, но все еще вызывает проблему при нажатии кнопки поиска.

José Orellana Jr 03.06.2018 07:07
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
2
690
1

Ответы 1

По поводу изменения ширины при нажатии на лупу. Я считаю, что это потому, что свойство :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. Я искренне ценю вашу помощь, Марвин!

José Orellana Jr 04.06.2018 02:39

Другие вопросы по теме