javascript - inputs - react label
React+Redux-Input onChange es muy lento cuando se escribe cuando la entrada tiene un valor del estado (5)
Obtuve mi entrada que está llena por un valor de mi estado.
<input id="flashVars" name="flashVars" type="text" value={settings.flashVarsValue} disabled={isDisabled} onChange={handleChange} />
Settings
es mi estado con Redux. Cuando pongo un valor en mi entrada, debo especificar una función onChange
. Esta es mi función onChange:
handleFlashVarsChange(e) {
let { dispatch } = this.props;
dispatch( changeFlashVarsValue(e.target.value) );
}
Cambia el valor del estado flashVarsValue
por el valor de la entrada. Pero cuando escribo mi entrada, se retrasa. No entiendo por qué debo llamar al envío cada vez que cambio el valor de entrada.
¿Hay alguna manera de que pueda dar menos retrasos?
Mi reductor:
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;
}
}
Mi acción:
export function changeFlashVarsValue(data) {
return {
type: ACTIONS.CHANGE_FLASHVARS_VALUE,
data: data
}
}
Gracias
El problema aquí es posiblemente volver a presentar. Está pasando "configuraciones" (todo su estado) a su componente que contiene la "entrada", y no sabemos cómo el resto de sus componentes conectados están acoplados al estado. Compruebe si, como resultado de la mutación del objeto de estado, está reenviando mucho más que solo la entrada en cada pulsación de tecla. La solución a esto es pasar más directamente en las partes específicas del estado que necesita de mapStateToProps (en este caso, tal vez solo pase "flashVarsValue" si eso es todo lo que necesita este componente, y asegúrese de que otros componentes no se pasen también state) y utilice PureRenderMixin o https://github.com/gaearon/react-pure-render Dan Abramov si está utilizando componentes de ES6 para no volver a procesarlos si sus accesorios no han cambiado.
La respuesta no es volver a representar su componente en cada pulsación de tecla, solo si el usuario deja de escribir. Algo como esto:
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;
}
La respuesta para mí fue usar el gancho del ciclo de vida shouldComponentUpdate. Esto ya ha sido dado como una respuesta en un comentario de Mike Boutin (hace aproximadamente un año :)), pero un ejemplo podría ayudar al próximo visitante aquí.
Tuve un problema similar, con la entrada de texto perdida y lenta y nerviosa. Estaba usando setState para actualizar el formData en mi evento onChange.
Descubrí que el formulario estaba haciendo una nueva representación completa con cada pulsación de tecla, ya que el estado había cambiado. Para detener esto, anulé la función:
shouldComponentUpdate(nextProps, nextState) {
return this.state.formErrors !== nextState.formErrors);
}
Muestro un panel de notificación de errores en el envío del formulario con cualquier error de validación nuevo o modificado, y esa es la única vez que necesito volver a renderizar.
Si no tiene componentes secundarios, probablemente podría simplemente configurar el componente form del componenteCompliqueActualización para que siempre devuelva falso.
Sé que esta es una pregunta antigua, pero si desea activar Cambiar en una entrada de texto, es probable que desee rebatir su evento. Este hilo hace un buen trabajo para descomponerlo, pero creo que esto funcionaría para el ejemplo de la operación:
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
Tuve un problema similar cuando estaba editando una grilla con un millón de filas, entonces lo que hice fue cambiar la lógica de actualización, en su caso handleChange para ser llamado solo en el evento ''onBlur'' en lugar de onChange. Esto solo activará la actualización cuando pierdas el foco. Pero no sé si esta sería una solución satisfactoria para usted ..