• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

React renderowanie inputów z pomocą .map()

VPS Starter Arubacloud
+1 głos
259 wizyt
pytanie zadane 16 lipca 2021 w JavaScript przez hakiros54 Obywatel (1,160 p.)

Witam, mam state który przechowuje tablice obiektów. Obiekt przechowuje id, value jednego inputa (require) i value drugiego. 
Za pomocą .map renderuję dwa kontrolowane inputy i problem jest w tym, że jak pisze coś w tym inpucie, to tracę na nim focus ponieważ inputy renderują się na nowo i nie wiem jak rozwiązać ten problem. Próbowałem zrobić drugą tablice i na niej uzywać .map a dane pobierać z innego state'u ale to nie pomogło.

 

const Other = ({data, setData}) => {
    const [requiremants, setRequiremants] = useState([]);
    const [inputArr, setInputArr] = useState([]);

    const addInput = () =>{
        const id = uuidv4();
        setRequiremants([...requiremants, {id: id, require: "", cost: 0}]);
        setInputArr([...inputArr, id]);
    }

    const handleInput = (e, id, key) =>{
        setRequiremants(
            requiremants.map(requiremant => {
                if(requiremant.id === id)
                    return {...requiremant, [key]: e.target.value}
                return requiremant
            })
        )
    }

    return (
        <section>
            <h1>Inne oczekiwania</h1>
            {
                inputArr.map(inputId => {
                    let requiremant;
                    for(let i = 0; i < requiremants.length; i++){
                        if(inputId === requiremants[i].id){
                            requiremant = requiremants[i];
                        }
                    }
                    return (
                        <div key = {uuidv4()}>  
                            <label>
                                Inne oczekiwania klienta:
                                <input type = "text" value = {requiremant.require} onChange = {e => handleInput(e,requiremant.id, "require")} />
                            </label>
                            <label>
                                Wycena indywidualna:
                                <input type = "number" value = {requiremant.cost} onChange = {e => handleInput(e,requiremant.id, "cost")} />
                            </label>
                        </ div>
                    )
                })
            }
            <button type="button" class="btn btn-primary" onClick = {addInput}>Dodaj oczekiwanie</button>
        </section>
    )
}

 

komentarz 16 lipca 2021 przez ScriptyChris Mędrzec (190,190 p.)

Możesz ten komponent udostępnić w jakimś sandboxie (np. https://codesandbox.io/ ), żeby można to było przetestować?

Całkiem na oko mogę stwierdzić, że problemem może być brak słówka break w pętli for, która szuka wartości dla zmiennej requiremant (swoją drogą jest tu literówka i powinno być: requirement) i ona może za każdym razem mieć inną wartość. Ale znalezienie przyczyny problemu będzie łatwiejsze, gdy się ten kod zdebuguje.

1
komentarz 16 lipca 2021 przez hakiros54 Obywatel (1,160 p.)
czułem, że źle napisałem to requirement ;P

https://codesandbox.io/embed/amazing-hawking-8mtq3?fontsize=14&hidenavigation=1&theme=dark

faktycznie zapomniałem dodać break ale to nic nie zmienia w tym wypadku, tylko będzie chodzić minimalnie dłużej.

1 odpowiedź

+1 głos
odpowiedź 16 lipca 2021 przez ScriptyChris Mędrzec (190,190 p.)
wybrane 22 lipca 2021 przez hakiros54
 
Najlepsza

Przyczyną re-renderingu w trakcie wypełniania inputów jest to, że za każdym razem przypisujesz otaczającemu im <div>owi inną (losową) wartość key. Ta wartość, owszem powinna być unikalna (w czym pomaga losowość), ale jednocześnie nie może zmieniać się między re-renderami, żeby React mógł zidentyfikować dany element.

https://reactjs.org/docs/lists-and-keys.html#keys

Zamiast <div key = {uuidv4()}> możesz użyć <div key = { requirement.id }>, ponieważ id danego requirement'a jest losowe (brane z uuidv4) i jednocześnie nadawane tylko w trakcie tworzenia inputów (czyli raz) - więc nie będzie się zmieniać pomiędzy re-renderami.


Na marginesie: klasy do elementów w React nadaje się poprzez className a nie class (w konsoli jest warning).

Podobne pytania

+1 głos
1 odpowiedź 225 wizyt
pytanie zadane 28 lutego 2022 w JavaScript przez Karson Obywatel (1,000 p.)
0 głosów
2 odpowiedzi 201 wizyt
0 głosów
1 odpowiedź 2,252 wizyt
pytanie zadane 9 września 2017 w Grafika i multimedia przez Norbert123 Początkujący (290 p.)

92,452 zapytań

141,262 odpowiedzi

319,085 komentarzy

61,854 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...