Jak zareaguje ustawienie fokusu na określonym polu tekstowym po renderowaniu komponentu?
Dokumentacja wydaje się sugerować użycie referencji, np .:
Ustaw ref="nameInput"
w moim polu wejściowym w funkcji renderowania, a następnie wywołaj:
this.refs.nameInput.getInputDOMNode().focus();
Ale gdzie mam to nazwać? Próbowałem już w kilku miejscach, ale nie mogę tego zrobić.
javascript
reactjs
Dave
źródło
źródło
<input>
elementu. Coś w stylu<input ref={ (component) => ReactDOM.findDOMNode(component).focus() } />
Odpowiedź @ Dhiraja jest prawidłowa, a dla wygody możesz użyć rekwizytu autoFocus, aby wejście automatycznie ustawiało ostrość po zamontowaniu:
Zauważ, że w jsx jest to
autoFocus
(wielka litera F) w przeciwieństwie do zwykłego starego kodu HTML, który nie rozróżnia wielkości liter.źródło
autofocus
atrybutu HTML5 , ale tak naprawdę używa gofocus()
w montażu DOM,react-dom
więc jest całkiem niezawodny.Od React 0.15 najbardziej zwięzłą metodą jest:
źródło
Skoncentruj się na montażu
Jeśli chcesz tylko skupić element podczas montowania (początkowo renderuje), wystarczy użyć atrybutu autoFocus.
Dynamiczny fokus
Aby dynamicznie kontrolować fokus, użyj funkcji ogólnej, aby ukryć szczegóły implementacji przed komponentami.
React 16,8 + Komponent funkcjonalny - użyj haka Focus
Pełna wersja demonstracyjna
React 16.3 + Class Components - useFocus
Pełna wersja demonstracyjna
źródło
(htmlElRef.current as any).focus()
i (2)return {htmlElRef, setFocus}
zamiast tablicy.useFocus
więcej niż jednego elementu.useFocus
napisane pismem maszynowym. gist.github.com/carpben/de968e377cbac0ffbdefe1ab56237573as const
masz), bardzo pouczające!set
drugą pozycję jakconst [inputRef, setInputFocus] = useFocus()
. To pasuje do useState więcej. Najpierw obiekt, a następnie seter tego obiektuJeśli chcesz tylko ustawić autofokus w React, jest to proste.
Jeśli chcesz po prostu wiedzieć, gdzie umieścić ten kod, odpowiedź znajduje się w module componentDidMount ().
v014.3
Przeczytaj dokumenty API tutaj: https://facebook.github.io/react/docs/top-level-api.html#reactdom.finddomnode
źródło
F
! (Uwaga dla siebie i innych, a nie dla odpowiedzi).W React 16.3 dodano nowy wygodny sposób na poradzenie sobie z tym poprzez utworzenie referencji w konstruktorze komponentu i użycie go w następujący sposób:
Aby uzyskać więcej informacji, możesz sprawdzić ten artykuł na blogu React.
Aktualizacja:
Począwszy od React 16.8 ,
useRef
hak może być używany w komponentach funkcji, aby osiągnąć ten sam wynik:źródło
Właśnie natknąłem się na ten problem i używam reagowania
15.0.115.0.2 i używam składni ES6 i nie otrzymałem tego, czego potrzebowałem od innych odpowiedzi, odkąd wer. 15 spadło kilka tygodni temu i niektórychthis.refs
właściwości były przestarzałe i usunięte .Ogólnie potrzebowałem:
Używam:
Skoncentruj pierwszy element wejściowy
Użyłem
autoFocus={true}
pierwszego<input />
na stronie, aby po zamontowaniu komponent uzyskał ostrość.Skoncentruj pierwszy element wejściowy na błędzie
Trwało to dłużej i było bardziej skomplikowane. Trzymam kod, który nie jest odpowiedni dla rozwiązania dla zwięzłości.
Redux Store / State
Potrzebuję stanu globalnego, aby wiedzieć, czy powinienem ustawić fokus i wyłączyć go, gdy był ustawiony, więc nie ustawiam ponownie fokusu podczas ponownego renderowania komponentów (użyję
componentDidUpdate()
do sprawdzenia ustawienia fokusa). )Można to zaprojektować według własnego uznania.
Komponent kontenerowy
Komponent będzie musiał mieć
resetfocus
ustawioną właściwość i callBack, aby wyczyścić właściwość, jeśli zakończy się ustawianie fokusu na sobie.Pamiętaj też, że zorganizowałem Action Creators w osobne pliki, głównie ze względu na to, że mój projekt jest dość duży i chciałem podzielić je na łatwiejsze do zarządzania części.
Komponent prezentacji
Przegląd
Ogólna idea jest taka, że każde pole formularza, które może zawierać błąd i być zogniskowane, musi sprawdzić się i czy musi skupić się na sobie.
Istnieje logika biznesowa, która musi się zdarzyć, aby określić, czy dane pole jest właściwym polem, na które należy ustawić fokus. Nie jest to pokazane, ponieważ będzie zależeć od indywidualnej aplikacji.
Po przesłaniu formularza to zdarzenie musi ustawić flagę globalnego fokusa
resetFocus
na wartość true. Następnie, gdy każdy komponent aktualizuje się sam, zobaczy, że powinien sprawdzić, czy uzyska fokus, a jeśli tak, wyślij zdarzenie, aby zresetować fokus, aby inne elementy nie musiały sprawdzać dalej.edytuj Na marginesie, miałem logikę biznesową w pliku „narzędzi”, po prostu wyeksportowałem metodę i wywołałem ją w każdym
shouldfocus()
metody.Twoje zdrowie!
źródło
Dokumenty React mają teraz sekcję na ten temat. https://facebook.github.io/react/docs/more-about-refs.html#the-ref-callback-attribute
źródło
autofocus
montować, po prostu szukałem elementu, który pozostanie skupiony podczas wprowadzania wartości. To zadziałało idealnie dla tego scenariusza. (przy użyciu reakcji 15)To nie jest już najlepsza odpowiedź. Począwszy od wersji 0.13,
this.refs
może być niedostępna do czasucomponentDidMount()
uruchomienia PO , w niektórych dziwnych przypadkach.Wystarczy dodać
autoFocus
znacznik do pola wejściowego, jak pokazano powyżej FakeRainBrigand.źródło
<input autofocus>
pól nie będzie się ładnie zachowywać<input>
renderowaniu poNr ref. Komentarz Dave'a do odpowiedzi @ Dhiraja; alternatywą jest użycie funkcji wywołania zwrotnego atrybutu ref na renderowanym elemencie (po pierwszym renderowaniu komponentu):
Więcej informacji
źródło
Uncaught TypeError: Cannot read property 'focus' of null
component && React.findDomNode...
. Przeczytaj więcej na ten temat tutaj: facebook.github.io/react/docs/…To jest właściwy sposób na automatyczne ustawianie ostrości. Gdy jako wartość referencyjną użyjesz wywołania zwrotnego zamiast ciągu, jest on automatycznie wywoływany. Masz dostępne ref bez konieczności dotykania DOM przy użyciu
getDOMNode
źródło
Zauważ, że żadna z tych odpowiedzi nie działała dla mnie z komponentem TextField w interfejsie użytkownika . Na Jak ustawić fokus na materialowym interfejsie tekstowym? Musiałem przeskoczyć przez kilka obręczy, aby to zadziałało:
źródło
focus()
musi być opóźnione do końca animacji.Możesz umieścić to wywołanie metody w funkcji renderowania. Lub w metodzie cyklu życia,
componentDidUpdate
źródło
Nie potrzebujesz
getInputDOMNode
?? w tym przypadku...Po prostu pobierz
ref
ifocus()
to, gdy komponent zostanie zamontowany - componentDidMount ...źródło
AutoFocus działał dla mnie najlepiej. Musiałem zamienić tekst na wejściowy z tym tekstem po podwójnym kliknięciu, więc oto co skończyło się na:
UWAGA: Aby rozwiązać problem polegający na tym, że React umieszcza kursor na początku tekstu, użyj tej metody:
Znaleziono tutaj: https://coderwall.com/p/0iz_zq/how-to-put-focus-at-the-end-of-an-input-with-react-js
źródło
Mam ten sam problem, ale mam też animację, więc mój kolega sugeruje użycie window.requestAnimationFrame
to jest atrybut ref mojego elementu:
źródło
Powinien być
źródło
Najprostszą odpowiedzią jest dodanie ref = "some name" w wejściowym elemencie tekstowym i wywołanie poniższej funkcji.
źródło
Aby przenieść fokus na nowo utworzony element, możesz zapisać identyfikator elementu w stanie i użyć go do ustawienia
autoFocus
. na przykładW ten sposób żadne z pól tekstowych nie zostanie zogniskowane na ładowaniu strony (tak jak chcę), ale kiedy naciśniesz przycisk „Dodaj”, aby utworzyć nowy rekord, wówczas ten nowy rekord zostanie zogniskowany.
Ponieważ
autoFocus
nie „uruchamia się” ponownie, chyba że komponent zostanie ponownie zamontowany, nie muszę się przejmować rozbrajaniemthis.state.focus
(tzn. Nie będzie nadal kradł fokusu, gdy aktualizuję inne stany).źródło
Przeczytałem prawie całą odpowiedź, ale nie widziałem
getRenderedComponent().props.input
Ustaw referencje wprowadzania tekstu
this.refs.username.getRenderedComponent().props.input.onChange('');
źródło
Po wypróbowaniu wielu powyższych opcji bez powodzenia stwierdziłem, że było tak, jak byłem,
disabling
a następnieenabling
dane wejściowe, które spowodowały utratę koncentracji.Miałem rekwizyt,
sendingAnswer
który wyłączyłby Wejście podczas odpytywania backendu.Gdy usunąłem wyłączony rekwizyt, wszystko znów zaczęło działać.
źródło
Zaktualizowana wersja, którą możesz sprawdzić tutaj
źródło
Ponieważ istnieje wiele przyczyn tego błędu, pomyślałem, że opublikuję również problem, z którym się spotkałem. Dla mnie problemem było to, że renderowałem moje dane wejściowe jako treść innego komponentu.
Tak nazwałem powyższy komponent:
źródło
Zgodnie ze zaktualizowaną składnią można użyć
this.myRref.current.focus()
źródło