Как создать синхронный и асинхронный ввод автозаполнения в ReactJS

Как и каждый пользователь, я обычно ленив и не хочу вводить все внутри ввода для поиска чего-либо, по крайней мере, зная, что когда мы сможем воспользоваться технологией, чтобы сделать нашу жизнь проще. Вот почему существуют поля автозаполнения, идея проста: вы набираете какой-то текст, который может соответствовать указанному параметру, и вы можете выбрать его, чтобы не вводить неверную информацию о чем-либо, поскольку вы можете получить все с вашего сервера или локально.

В этой статье мы покажем вам, как легко внедрить компонент автозаполнения в ваш проект, чтобы облегчить жизнь ваших пользователей.

Требования

Для реализации настолько быстрого и простого компонента автозаполнения мы рекомендуем использовать react-autocomplete модуль. Этот модуль предлагает WAI-ARIA-совместимый компонент автозаполнения React (combobox), который можно легко настроить в соответствии с вашими потребностями. Чтобы использовать его, продолжите установку модуля в своем проекте, используя следующую команду, используя NPM в своем терминале:

npm install --save react-autocomplete

После установки вы сможете импортировать компоненты как Autocomplete от 'react-autocomplete', Для получения дополнительной информации об этой библиотеке, пожалуйста, посетите официальный репозиторий на Github здесь.

А. Создание синхронного автозаполнения

Если вы хотите использовать поле автозаполнения, предлагающее локальные данные (уже доступный массив объектов в классе), вам просто нужно определить данные внутри состояния класса и загрузить их в подпункт элементов компонента автозаполнения. Данные будут в формате массива, который соответствует только объектам. Каждый объект является элементом списка автозаполнения, значения могут быть названы так, как вы хотите (так как вы можете определить, какие свойства объекта будут отображаться при автозаполнении). В следующем примере реализовано 6 базовых опор компонента, мы определяем обратный вызов для основных действий, например, когда ввод изменяется или пользователь выбирает какую-либо опцию автозаполнения.

Кроме того, мы настраиваем структуру каждого отображаемого элемента с помощью обратного вызова renderItem и объявляем начальное значение, которое в этом случае будет пустым, используя свойство value объявленного состояния:

import React from 'react';
// Import the Autocomplete Component
import Autocomplete from 'react-autocomplete';
export default class App extends React.Component {
constructor(props, context) {
super(props, context);
// Set initial State
this.state = {
// Current value of the select field
value: "",
// Data that will be rendered in the autocomplete
autocompleteData: [
{
label: 'Apple',
value: 1
},
{
label: 'Microsoft',
value: 2
},
{
label: 'Me, Myself and I',
value: 3
}
]
};
// Bind `this` context to functions of the class
this.onChange = this.onChange.bind(this);
this.onSelect = this.onSelect.bind(this);
this.getItemValue = this.getItemValue.bind(this);
this.renderItem = this.renderItem.bind(this);
}
/**
* Callback triggered when the user types in the autocomplete field
*
* @param {Event} e JavaScript Event
* @return {Event} Event of JavaScript can be used as usual.
*/
onChange(e){
this.setState({
value: e.target.value
});
console.log("The Input Text has changed to ", e.target.value);
}
/**
* Callback triggered when the autocomplete input changes.
*
* @param {Object} val Value returned by the getItemValue function.
* @return {Nothing} No value is returned
*/
onSelect(val){
this.setState({
value: val
});
console.log("Option from 'database' selected : ", val);
}
/**
* Define the markup of every rendered item of the autocomplete.
*
* @param {Object} item Single object from the data that can be shown inside the autocomplete
* @param {Boolean} isHighlighted declares wheter the item has been highlighted or not.
* @return {Markup} Component
*/
renderItem(item, isHighlighted){
return (
{item.label}
);
}
/**
* Define which property of the autocomplete source will be show to the user.
*
* @param {Object} item Single object from the data that can be shown inside the autocomplete
* @return {String} val
*/
getItemValue(item){
// You can obviously only return the Label or the component you need to show
// In this case we are going to show the value and the label that shows in the input
// something like "1 - Microsoft"
return `${item.value} - ${item.label}`;
}
render() {
return (
);
}
}

Предыдущий класс будет отображать очень простое автозаполнение, которое выглядит следующим образом:

Синхронизация примера автозаполнения React

Б. Создание асинхронного автозаполнения

Обычно автозаполнение также реализует асинхронный интерфейс, что означает, что когда пользователь вводит данные, некоторая логика запускается в фоновом режиме и получает некоторую информацию с сервера. Благодаря методологии и компоненту React этого не так сложно достичь, так как мы используем состояние React, чтобы выполнить тяжелую работу за нас.

Процесс реализации автозаполнения будет таким же, как и синхронный, однако меняется только одна вещь — источник данных. Первоначально мы устанавливаем autocompleteData в пустой массив, поскольку мы должны загрузить эту информацию с нашего сервера. Логика загрузки удаленных данных в автозаполнение проста, нам просто нужно обновить состояние autocompleteData с удаленными данными и все тут! Очевидно, что структура данных должна совпадать с заявленной в нашей логике локально (для получения меток, значений и т. Д.). В следующем примере функция для извлечения данных из удаленного источника retrieveDataAsynchronouslyэта функция вызывается внутри обратного вызова onChange, который должен быть явно объявлен. Функция получает в качестве первого аргумента текущий текст ввода, который будет использоваться вашей серверной логикой для отправки некоторых данных в соответствии с запрошенным пользователем:

import React from 'react';
// Import the Autocomplete Component
import Autocomplete from 'react-autocomplete';
export default class App extends React.Component {
constructor(props, context) {
super(props, context);
// Set initial State
this.state = {
// Current value of the select field
value: "",
// Data that will be rendered in the autocomplete
// As it is asynchronous, it is initially empty
autocompleteData: []
};
// Bind `this` context to functions of the class
this.onChange = this.onChange.bind(this);
this.onSelect = this.onSelect.bind(this);
this.getItemValue = this.getItemValue.bind(this);
this.renderItem = this.renderItem.bind(this);
this.retrieveDataAsynchronously = this.retrieveDataAsynchronously.bind(this);
}
/**
* Updates the state of the autocomplete data with the remote data obtained via AJAX.
*
* @param {String} searchText content of the input that will filter the autocomplete data.
* @return {Nothing} The state is updated but no value is returned
*/
retrieveDataAsynchronously(searchText){
let _this = this;
// Url of your website that process the data and returns a
let url = `mywebsite/searchApi?query=${searchText}`;
// Configure a basic AJAX request to your server side API
// that returns the data according to the sent text
let xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'json';
xhr.onload = () => {
let status = xhr.status;
if (status == 200) {
// In this example we expects from the server data with the structure of:
// [
//    {
//        label: "Some Text",
//        value: 1,
//    },
//    {
//        label: "Some Other Text",
//        value: 1,
//    },
// ]
// But you can obviously change the render data :)
// Update the state with the remote data and that's it !
_this.setState({
autocompleteData: xhr.response
});
// Show response of your server in the console
console.log(xhr.response);
} else {
console.error("Cannot load data from remote source");
}
};
xhr.send();
}
/**
* Callback triggered when the user types in the autocomplete field
*
* @param {Event} e JavaScript Event
* @return {Event} Event of JavaScript can be used as usual.
*/
onChange(e){
this.setState({
value: e.target.value
});
/**
* Handle the remote request with the current text !
*/
this.retrieveDataAsynchronously(e.target.value);
console.log("The Input Text has changed to ", e.target.value);
}
/**
* Callback triggered when the autocomplete input changes.
*
* @param {Object} val Value returned by the getItemValue function.
* @return {Nothing} No value is returned
*/
onSelect(val){
this.setState({
value: val
});
console.log("Option from 'database' selected : ", val);
}
/**
* Define the markup of every rendered item of the autocomplete.
*
* @param {Object} item Single object from the data that can be shown inside the autocomplete
* @param {Boolean} isHighlighted declares wheter the item has been highlighted or not.
* @return {Markup} Component
*/
renderItem(item, isHighlighted){
return (
{item.label}
);
}
/**
* Define which property of the autocomplete source will be show to the user.
*
* @param {Object} item Single object from the data that can be shown inside the autocomplete
* @return {String} val
*/
getItemValue(item){
// You can obviously only return the Label or the component you need to show
// In this case we are going to show the value and the label that shows in the input
// something like "1 - Microsoft"
return `${item.value} - ${item.label}`;
}
render() {
return (
);
}
}

Когда пользователь вводит автозаполнение, данный текст отправляется на сервер с запросом AJAX, и он должен возвращать в качестве ответа массив с некоторыми данными, совпадающими с предоставленным пользователем текстом. Состояние обновляется данными, отправленными с сервера, и пользователь может выбрать опцию. Обратите внимание, что реализация здесь создает ajax-запрос, который выполняется каждый раз, когда пользователь нажимает клавишу, что означает много запросов, поэтому вы можете захотеть отменить функцию как-нибудь. Помните, что вы можете настроить параметры ввода и автозаполнения по своему усмотрению используя только CSS путем изменения свойства menuStyle.

Ссылка на основную публикацию
Adblock
detector