2016-01-17 19 views
10

Rozglądając się, aby zobaczyć, w jaki sposób inni deweloperzy zajmują się wprowadzaniem fokusu podczas pracy z Redux, natknąłem się na pewne ogólne wskazówki dotyczące ReactJS components such as this. Obawiam się jednak, że funkcja focus() jest niezbędna i mogłem zobaczyć dziwne zachowania możliwe, gdy wiele komponentów walczy o skupienie. Czy istnieje sposób radzenia sobie z fokusem? Czy ktokolwiek zajmuje się pragmatycznym ustawianiem ostrości przy użyciu redux ireagowania i czy są to jakich technik używasz?Jak radzić sobie z fokusowaniem przy użyciu deklaratywnych/funkcjonalnych bibliotek takich jak Redux i ReactJS?

pokrewne:

+3

Redux i węzłów DOM/funkcje DOM, nie mają nic wspólnego ze sobą naprawdę ... nie jestem pewien, co jak czekasz Redux być zaangażowane. Dlaczego wiele komponentów walczy o skupienie i jakiego rodzaju dziwnych zachowań próbujesz uniknąć? – azium

+0

Jak powiedział azium, redux to tylko sposób zarządzania i przechowywania stanu aplikacji. Być może powinieneś ponownie sformułować swoje pytanie - czy pytasz o to, jak zarządzać wieloma komponentami, które mają ustawioną fokus() i kiedy są renderowane na stronie, chcesz zdecydować, która z nich rzeczywiście się skupia? Myślę, że to zależy wyłącznie od twojej aplikacji!Domyślnie byłby to ostatni, który wydawał mi się ostatni. Weź również pod uwagę atrybut "autofocus". –

+1

Dominic, opisujesz moje obawy całkiem dobrze. Wiele komponentów, które chcą ustawić ostrość, ale wygra tylko jeden. Ostatecznie renderowany widok nie będzie zsynchronizowany z reprezentacją deklaratywną, częściowo dlatego, że z wezwaniem do fokusa() nie jest już deklaratywny, a także dlatego, że akt skupienia powoduje skutki uboczne. – jpierson

Odpowiedz

8

Moje podejście jest użycie ref zwrotnego, który jest swego rodzaju onRenderComplete elementu. W tym oddzwonieniu mogę skupić się (warunkowo, jeśli to konieczne) i uzyskać referencję dla przyszłego ogniskowania.

Jeśli dane wejściowe są renderowane warunkowo po uruchomieniu działania, to odwołanie zwrotne powinno wywołać fokus, ponieważ ref nie istnieje jeszcze bezpośrednio po wywołaniu akcji, ale dopiero po wykonaniu renderowania. Radzenie sobie z componentDidUpdate dla takich rzeczy jak focus wydaje się tylko bałaganem.

// Composer.jsx -- contains an input that will need to be focused somewhere else 

class Composer extends Component { 
    render() { 
    return <input type="text" ref="input" /> 
    } 

    // exposed as a public method 
    focus() { 
    this.refs.input.focus() 
    } 
} 

// App.jsx 

@connect(
    state => ({ isComposing: state.isComposing }), 
    ... 
) 
class App extends Component { 
    render() { 
    const { isComposing } = this.props // or props, doesn't matter 
    return (
     <div> 
     <button onClick={::this._onCompose}>Compose</button> 
     {isComposing ? <Composer ref={c => { 
      this._composer = c 
      this._composer && this._composer.focus() // issue initial focus 
     }} /> : null} 
     </div> 
    ) 
    } 

    _onCompose() { 
    this.props.startComposing() // fire an action that changes state.isComposing 

    // the first time the action dispatches, this._composer is still null, so the ref takes care of the focus. After the render, the ref remains so it can be accessed: 

    this._composer && this._composer.focus() // focus if ref already exists 
    } 
} 

Dlaczego nie autoFocus lub isFocued prop?

Jak HTMLInputElement ma value jako rekwizyt, ale focus() jako metody - a nie isFocused rekwizyt - Chciałbym zachować przy użyciu metod poradzić. isFocused może uzyskać wartość, ale jeśli użytkownik zaciera się z wejścia, co dzieje się z tą wartością? To będzie niezsynchronizowane. Ponadto, jak wspomniano w komentarzach, autoFocus może kolidować z wieloma komponentami:

A więc jak wybierać między rekwizytami a metodami?

Dla większości przypadków rekwizytów będzie odpowiedź. Metody mogą być używane tylko w przypadku "pożaru i zapomnienia", na przykład scrollToBottom na czacie, gdy pojawia się nowa wiadomość, scrollIntoView i tym podobne. Są to jednorazowe zachowania, o które sklep nie dba, a użytkownik może zmienić interakcję, więc propozycja boolowska nie pasuje. W przypadku wszystkich innych rzeczy chodziłem z rekwizytami.

Oto jsbin:

http://jsbin.com/waholo/edit?html,js,output

Powiązane problemy