Подтвердить что ты не робот

React + Redux - вход onChange очень медленный при вводе, когда вход имеет значение из состояния

Я получил свой вклад, который заполняется значением из моего состояния.

<input id="flashVars" name="flashVars" type="text" value={settings.flashVarsValue} disabled={isDisabled} onChange={handleChange} />

Settings - мое состояние с Redux. Когда я добавляю значение в свой ввод, я должен указать функцию onChange. Это моя функция onChange:

handleFlashVarsChange(e) {
  let { dispatch } = this.props;

  dispatch( changeFlashVarsValue(e.target.value) );
}

Измените значение состояния flashVarsValue для значения ввода. Но когда я ввожу свой ввод, он отстает. Я не понимаю, почему я должен вызывать отправку каждый раз, когда меняю входное значение.

Есть ли способ, который может дать меньше лагов?

Мой редуктор:

import { ACTIONS } from '../utils/consts';

const initialState = {
  ...
  flashVarsValue: '',
  ...
};

export function formSettings(state = initialState, action = '') {
  switch (action.type) {

    ...

    case ACTIONS.CHANGE_FLASHVARS_VALUE:
      return Object.assign({}, state, {
        flashVarsValue: action.data
      });

    default:
      return state;
  }
}

Мое действие:

export function changeFlashVarsValue(data) {
  return {
    type: ACTIONS.CHANGE_FLASHVARS_VALUE,
    data: data
  }
}

Спасибо

4b9b3361

Ответ 1

У меня была аналогичная проблема, когда я редактировал сетку с миллионом строк, так что я сделал, чтобы изменить логику обновления, в вашем случае handleChange будет вызываться только в событии onBlur вместо onChange. Это приведет только к обновлению, когда вы потеряете фокус. Но не знаю, будет ли это удовлетворительным решением для вас.

Ответ 2

Проблема здесь, возможно, повторится. Вы передаете "настройки" (все ваше состояние) вашему компоненту, содержащему "enter", и мы не знаем, как остальные ваши подключенные компоненты связаны с состоянием. Убедитесь, что в результате мутирования объекта состояния вы реверсируете гораздо больше, чем просто ввод на каждое нажатие клавиши. Решением этого является более непосредственный переход в определенные части состояния, которые вам нужны от mapStateToProps (в этом случае, возможно, только пройти в "flashVarsValue", если это требуется всем этим компонентам, и убедиться, что другие компоненты также не переданы state) и использовать PureRenderMixin или Dan Abramov https://github.com/gaearon/react-pure-render, если вы используете компоненты ES6, чтобы не повторно отображать, если ваши реквизиты не изменились

Ответ 3

Ответ для меня заключался в том, чтобы использовать hookCycleonUpdate. Это уже было дано как ответ в комментарии Майка Бутина (около года назад:)), но пример может помочь следующему посетителю здесь.

У меня была аналогичная проблема: потеря текста была медленной и медленной. Я использовал setState для обновления formData в моем событии onChange.

Я обнаружил, что форма выполняла полную повторную визуализацию с каждым нажатием клавиши, поскольку состояние изменилось. Поэтому, чтобы остановить это, я перепробовал функцию:

shouldComponentUpdate(nextProps, nextState) {
   return this.state.formErrors !== nextState.formErrors);
}

Я показываю панель уведомлений об ошибках при отправке формы с любыми новыми или измененными ошибками проверки и что единственный раз, когда мне нужно повторно выполнить рендеринг.

Если у вас нет дочерних компонентов, возможно, вы можете просто установить компонент формы shouldComponentUpdate, чтобы он всегда возвращал false.

Ответ 4

Ответ не состоит в том, чтобы повторно визуализировать ваш компонент при каждом нажатии клавиши, только если пользователь прекращает вводить текст. Примерно так:

shouldComponentUpdate(nextProps, nextState) {
    if (!textInputReRender)
        return false;
    else
        return true;
}

onTextInputChange = (propName, propValue) => {
    if (inputChangeTimerId)
        clearTimeout(inputChangeTimerId);

    inputChangeTimerId = setTimeout(() => {
        inputChangeTimerId = null;
        const newState = {};

        textInputReRender = true;

        newState[propName] = propValue;
        this.setState(newState);
    }, 500);

    textInputReRender = false;
}

Ответ 5

Я знаю, что это старый вопрос, но если вы хотите запустить onChange на текстовом входе, вы, вероятно, захотите отменить свое событие. Этот поток отлично справляется с этим, но я думаю, что это сработает для примера op:

import debounce from 'debounce'                                      

function debounceEventHandler(...args) {
  const debounced = debounce(...args)
  return function (e) {
    e.persist();
    return debounced(e);
  }
}                                                                      
const Container = React.createClass({
  handleFlashVarsChange(e) {
    let { dispatch } = this.props;
    //basic redux stuff
    this.props.changeFlashVarsValue(e.target.value));
  },
  render() {
    const handleChange = debounceEventHandler(this.handleFlashVarsChange, 15);
    return (
      <input id="flashVars" onChange={handleChange} />
    )
  }                                                                         
}
//...prep and return your redux container

Ответ 6

Вместо этого используйте onChangeText

import { TextInput, View} from "react-native";  
import { connect } from "react-redux"; 
import React, { Component, useState } from "react";

function SearchTextInput(props) {
  const { keyword = "", setKeyword } = props; 
  return (
     <TextInput
       style={styles.searchInputText}
       placeholder={"placeholder here"}
       value={keyword}
       onChangeText={setKeyword(t)}
     />
  );
}

const mapStateToProps = state => {
  return {
    keyword: state.search.keyword,
    search: state.search
  };
};
const mapDispatchToProps = dispatch => ({
  setKeyword: payload => dispatch(({type:'updateSearchText', keyword: payload }))
});
export default connect(
  mapStateToProps,
  mapDispatchToProps
)(SearchTextInput);