Upload plików w aplikacji jest dość często pojawiającą się funkcjonalnością. Pozwala na wysyłanie plików do innych osób, serwisów, dostarczaniu danych do aplikacji żeby nie musieć wypełniać ich manualnie lub zwykłym umieszczaniu zdjęć na stronie. Podczas tworzenia aplikacji możemy wykorzystać jedną z wielu bibliotek, która dodaje w naszej aplikacji frontendowej taką funkcjonalność ale może da się to zrobić samemu?
input type="file"
Tak naprawdę stworzenie takiej funkcjonalności bez żadnej bibliotek nie jest niczym trudnym. Musimy się tylko oprzeć o znany element HTML - input z odpowiednim typem file
Już samo takie polecenie powoduje, iż wyświetla nam się przycisk wraz z informacją dotyczącą jaki plik wybraliśmy.
See the Pen Input file by Aleksander (@Feridum) on CodePen.
Oczywiście na tym nie kończą się możliwości tego elementu ponieważ razem z tym typem dostajemy kilka atrybutów, którymi możemy sterować pracą inputa. Znajdziemy tam:
- accept - określamy jakie typy plików lub rozszerzeń użytkownik może wybrać
- capture- jeżeli dopiszemy ten atrybut to podczas wyboru pliku do uploadu automatycznie będzie wykorzystana kamera lub mikrofon (w zależności od atrybutu accept) o ile są dostępne
- multiple - atrybut typu boolean, który określa czy można wybrać kilka plików
- files - pod tym atrybutem znajdują się nasze pliki
Warto jeszcze na chwilę zatrzymać się przy atrybucie accept. Dopuszcza on kilka możliwości ustawiania wartości:
- Rozszerzenie pliku, który chcemy dopuścić np.: .png
- Poprawny typ MIME np.: image/png
- Tekst audio/*, który oznacza dowolny plik dźwiękowy
- Tekst video/*, który oznacza dowolny plik wideo
- Tekst image/*, który oznacza dowolny obrazek
Dodatkowo możemy podać wiele wartości oddzielając je przecinkiem np.: accept=".png,.jpg".
Upload pliku w React
Jednak rzadko kiedy widzimy takie pole, ponieważ nie pasuje ono zwykle do wyglądu strony i taki element psułby wizualnie całość aplikacji. Zamiast tego widzimy zwykłe przyciski lub inne mechanizmy, które ukrywają input a wystawiają ładnie wyglądający element. Jak to zrobić w React.js? Przykładowy komponent może wyglądać następująco:
Przy tworzeniu takich komponentów pierwszy krok to będzie umieszczenie oraz ukrycie natywnego <input type="file"/>. Dalej wykorzystujemy mechanizm ref'a w React'cie aby dostać się do tego elementu i go kliknąć oraz potem by pobrać odpowiedni plik z atrybutu files. Cała reszta to tak naprawdę odpowiednie ostylowanie naszego komponentu. Prawda, iż proste?
Testy w React
Została ostatnia rzecz do zrobienia. Skoro mamy komponent w React'cie to warto go przetestować. Ostatnio testuję komponenty React'a z wykorzystaniem react-testing-library (jeśli korzystacie z Enzyma to polecam spróbować tej biblioteki - osobiście znacznie lepiej pisze mi się teraz testy). Oczywiście to co tutaj pokażę to jest najprostszy przypadek i pokazuje tylko jak można podejść do tego problemu. Każdy formularz jest unikalny i będziemy w nim testować coś innego.
Tak może wyglądać test do komponentu, który stworzyliśmy przed chwilą. Najważniejsza jest ta część, która odpowiada za stworzenie pliku w JS oraz zasymulowanie wybrania go przez użytkownika.
Tworzenie pliku:
Symulacja wybrania pliku przez użytkownika:
Całość kodu możecie zobaczyć na CodeSandbox. A jak u was wygląda upload plików? Rozwiązujecie to podobnie czy zupełnie inaczej? A może wolicie biblioteki - jeżeli tak to z czego korzystacie i dlaczego?