Wątek przeniesiony 2023-07-31 10:40 z JavaScript przez Riddle.

Jak poprawnie pokazać podgląd uploadowanego obrazka?

0

Mam komponent ktory sklada sie z img oraz inputa. Na inpucie mam dodany event listener

function validateExternalUrl(url: string): void {
    // resetImagePreview();
    const addImageButton = addImageButtonRef.current!;

    if (!validateLink(url)) {
        showValidationError(
            _t("image_upload.external_url_validation_error"),
            "danger"
        );
        setUploaded(false);
        addImageButton.disabled = true;
    } else {
        hideValidationError();
        addImageButton.disabled = false;
        setUploaded(true);
    }
}

Tutaj sprawdzam czy link do img jest prawidlowy i jesli tak, to wolam setUploaded ktore wlasnnie pokazuje moje img zamiast pola do uploadowania pliku. Problem w tym ze w momencie w ktorym walidacja jest peawidlowa i pojawia sie moje img (prawidlowo), to gdy zmienie wartosc inputa w taki sposob ze walidacja dalej przechodzi, to obrazek sie nie updatuje. Tak wyglada img

<div className="drag-area">
	<img src={linkInputRef.current.value}></img>
</div>

Czyli pobieram wartosc z inputa w ktorym jest url ale mimo tego ze url sie zmienia, to img sie nie re-renderuje. Co powinienem zmienic?

1
<img src={linkInputRef.current.value}></img>

Ale po co ci tutaj ref? Ogólnie to zwykle robi się tak (uproszczony przykład):

function Foo() {
    const [imageUrl, setImageUrl] = useState('cat.jpg');
    const handleClick = () => {
       setImageurl(url => url == 'cat.jpg'? 'dog.jpg' : 'cat.jpg');
    };
    return <img onClick={handleClick} src={imageUrl} />
}

Czyli gdzieś w aplikacji powinieneś zapisywać, jaki ma adres mieć obrazek (np. używając useState(), ale to jedna z możliwości).

A zmieniając stan robi się to w ten sposób, żeby React załapał zmiany (tutaj przez wywołanie setttera danego stanu: setImageUrl), wtedy React sobie przerenderuje.

A jeśli będziesz zmieniać sobie obiekty na pałę np. addImageButton.disabled = true; to React nie zrozumie, co zmieniłeś. I może przez przypadek to zadziała, że akurat się przerenderuje z innego powodu.

No i addImageButton jest włączony/wyłączony też można umieścić jako stan np.:

const [addImageButtonEnabled, setAddImageButtonEnabled] = useState(true);
//...
// w hooku
setUploaded(false);
setAddImageButtonEnabled(false);
// renderowanie
<button disabled={!setAddImageButtonEnabled}>....</button>

Serio, zalecałbym przejście jakiegoś solidnego tutoriala do Reacta czy poczytanie dokumentacji, bo ciągle próbujesz robić coś naokoło, jeśli chodzi o same założenia tego, jak React działa. Próbujesz pisać na czystym DOM, podczas gdy sens korzystania z Reacta jest właśnie taki, żeby nie korzystać z czystego DOM i nie latać po właściwościach elementów DOM*, tylko żeby to React nam ten DOM renderował, a my możemy być skupieni na tym, w jaki sposób przepływają dane w dół drzewa i w jaki sposób możemy spowodować zmianę danych, którą wykryje React i nam przerenderuje komponenty.

*chyba, że trzeba, w ostateczności. Bo są sytuacje, kiedy takie podejście jest potrzebne, np. przy integracji różnych bibliotek nie-reactowych z Reactem. Albo jak robisz coś, czego inaczej się nie da itp.

0
LukeJL napisał(a):
<img src={linkInputRef.current.value}></img>

Ale po co ci tutaj ref? Ogólnie to zwykle robi się tak (uproszczony przykład):

function Foo() {
    const [imageUrl, setImageUrl] = useState('cat.jpg');
    const handleClick = () => {
       setImageurl(url => url == 'cat.jpg'? 'dog.jpg' : 'cat.jpg');
    };
    return <img onClick={handleClick} src={imageUrl} />
}

Czyli gdzieś w aplikacji powinieneś zapisywać, jaki ma adres mieć obrazek (np. używając useState(), ale to jedna z możliwości).

A zmieniając stan robi się to w ten sposób, żeby React załapał zmiany (tutaj przez wywołanie setttera danego stanu: setImageUrl), wtedy React sobie przerenderuje.

A jeśli będziesz zmieniać sobie obiekty na pałę np. addImageButton.disabled = true; to React nie zrozumie, co zmieniłeś. I może przez przypadek to zadziała, że akurat się przerenderuje z innego powodu.

No i addImageButton jest włączony/wyłączony też można umieścić jako stan np.:

const [addImageButtonEnabled, setAddImageButtonEnabled] = useState(true);
//...
// w hooku
setUploaded(false);
setAddImageButtonEnabled(false);
// renderowanie
<button disabled={!setAddImageButtonEnabled}>....</button>

Serio, zalecałbym przejście jakiegoś solidnego tutoriala do Reacta czy poczytanie dokumentacji, bo ciągle próbujesz robić coś naokoło, jeśli chodzi o same założenia tego, jak React działa. Próbujesz pisać na czystym DOM, podczas gdy sens korzystania z Reacta jest właśnie taki, żeby nie korzystać z czystego DOM i nie latać po właściwościach elementów DOM*, tylko żeby to React nam ten DOM renderował, a my możemy być skupieni na tym, w jaki sposób przepływają dane w dół drzewa i w jaki sposób możemy spowodować zmianę danych, którą wykryje React i nam przerenderuje komponenty.

*chyba, że trzeba, w ostateczności. Bo są sytuacje, kiedy takie podejście jest potrzebne, np. przy integracji różnych bibliotek nie-reactowych z Reactem. Albo jak robisz coś, czego inaczej się nie da itp.

Dzieki, czyli zawsze gdy chce wyrenderowac zawartosc inputa gdziekolwiek indziej to powinienem uzyc useState i nadac onInput zeby zawsze nadpisywal ten state.

0

Tutaj fajnie opisali, na czym polega, że masz deklaratywne GUI, a zmieniasz stanem
https://react.dev/learn/reacting-to-input-with-state

No i zwykle faktycznie tak się powinno robić, chociaż nie byłbym takim radykałem, że zawsze. Bo może robiąc coś konkretnego będzie potrzeba użyć tej nieszczęsnej refki i operować bezpośrednio na elementach DOM, ale co do zasady to powinien być wyjątek, a nie reguła.

Tu masz opisane sytuacje, kiedy refki się przydają i na co uważać, jak się ich używa: https://react.dev/learn/manipulating-the-dom-with-refs

useState

useState i useReducer to wbudowany system zarządzania stanem, ale są jeszcze osobne biblioteki do zarządzania stanem (np. Redux, Mobx, Zustand itp.), których też można użyć, jeśli się czuje taką potrzebę.

0
LukeJL napisał(a):

Tutaj fajnie opisali, na czym polega, że masz deklaratywne GUI, a zmieniasz stanem
https://react.dev/learn/reacting-to-input-with-state

No i zwykle faktycznie tak się powinno robić, chociaż nie byłbym takim radykałem, że zawsze. Bo może robiąc coś konkretnego będzie potrzeba użyć tej nieszczęsnej refki i operować bezpośrednio na elementach DOM, ale co do zasady to powinien być wyjątek, a nie reguła.

Tu masz opisane sytuacje, kiedy refki się przydają i na co uważać, jak się ich używa: https://react.dev/learn/manipulating-the-dom-with-refs

useState

useState i useReducer to wbudowany system zarządzania stanem, ale są jeszcze osobne biblioteki do zarządzania stanem (np. Redux, Mobx, Zustand itp.), których też można użyć, jeśli się czuje taką potrzebę.

Dzieki wielkie, faktycznie trzeba przeczytac porzadnie dokumentacje :D

1 użytkowników online, w tym zalogowanych: 0, gości: 1