2015-10-21 8 views
25

Ho ricevuto il mio input che è stato riempito da un valore dal mio stato.React + Redux - Input onChange è molto lento quando si digita quando l'input ha un valore dallo stato

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

Settings è il mio stato con Redux. Quando inserisco un valore nel mio input, devo specificare una funzione onChange. Questa è la mia funzione onChange:

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

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

cambia il valore dello stato flashVarsValue per il valore dell'ingresso. Ma quando digito il mio input, è in ritardo. Non capisco perché dovrei chiamare il dispatch ogni volta che cambio il valore di input.

C'è qualche modo in grado di dare meno ritardi?

mio riduttore:

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; 
    } 
} 

mia azione:

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

Grazie

+1

È questo il ritardo con i Redux dev-tools o senza? Provalo senza prima e vedi se questo aiuta. –

+0

Non uso ancora gli strumenti di sviluppo di Redux, ho appena iniziato ad usarlo –

+0

Puoi mostrare il codice per aggiornare il tuo negozio? Non sono sicuro di vedere abbastanza codice per aiutarti. –

risposta

8

Ho avuto un problema simile quando stavo montando una griglia con un milione di righe, quindi quello che ho fatto doveva cambiare la logica di aggiornamento, nel tuo caso handleChange essere chiamato solo sull'evento 'onBlur' invece di onChange. Questo attiverà l'aggiornamento solo quando perderai la concentrazione. Ma non so se questa sarebbe una soluzione soddisfacente per voi ..

+0

Grazie di averlo provato lunedì;) –

+0

@MikeBoutin ha funzionato per te? Ho lo stesso problema – antoine129

+0

Prova a gestire l'aggiornamento con shouldComponentUpdate, ha funzionato per me –

3

Il problema qui è possibilmente ri-rendering. Stai trasmettendo "impostazioni" (il tuo intero stato) al tuo componente che contiene "input" e non sappiamo come il resto dei tuoi componenti connessi sia stato accoppiato. Controlla se, a seguito del mutamento dell'oggetto di stato, stai eseguendo il rerendering molto più dell'input di ogni tasto. La soluzione a questo è passare più direttamente nelle parti specifiche dello stato di cui hai bisogno da mapStateToProps (in questo caso, forse solo passare in "flashVarsValue" se è tutto ciò di cui ha bisogno questo componente e assicurarsi che anche gli altri componenti non siano passati all'intero stato) e utilizzare PureRenderMixin o Dan Abramov's https://github.com/gaearon/react-pure-render se stai usando i componenti ES6 per non ri-renderizzare se i tuoi oggetti di scena non sono cambiati

4

La risposta per me era usare l'hook del ciclo di vita shouldComponentUpdate. Questo è già stato dato come risposta in un commento di Mike Boutin (circa un anno fa :)), ma un esempio potrebbe aiutare il prossimo visitatore qui.

Ho avuto un problema simile, con l'input di testo perso e lento e nervoso. Stavo usando setState per aggiornare i formData nel mio evento onChange.

Ho trovato che il modulo stava eseguendo un re-rendering completo con ogni pressione di un tasto, poiché lo stato era cambiato. Quindi, per fermare questo, ho calpestato la funzione:

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

mostro un pannello di notifica di errore sul modulo di presentazione, con eventuali errori nuovi o modificati di validazione, e questa è l'unica volta che ho bisogno di ri-renderizzare.

Se non si dispone di componenti secondari, è probabile che sia possibile impostare il valore del componente dovrebbe shouldComponentUpdate per restituire sempre false.

2

So che questa è una domanda vecchia, ma se si desidera attivare l'opzione Cambia in un input di testo, è probabile che si desideri annullare l'evento.This thread fa un buon lavoro rottura verso il basso, ma credo che questo dovrebbe funzionare per esempio del PO:

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 
+0

Stavo pensando a questo - MA - se il tuo antirimbalzo si imposta dopo 1 secondo, e il tuo input si basa su un cambiamento di stato da aggiornare (ri-render), non dovresti aspettare 1 secondo per vedere il cambiamento di "foo" a 'bar', per esempio? In realtà non vedresti le singole "b", "ba", "bar", vero? – besseddrest

+0

funziona solo con componenti non controllati, se si utilizza un componente controllato e il valore viene rimosso, l'input non verrà aggiornato. – camou

Problemi correlati