2017-01-17 73 views
11

Może ktoś proszę wyjaśnić, jak naprawić ten błądReact Warning: flattenChildren (...): spotykane dwoje dzieci z tym samym kluczem

Warning: flattenChildren (...): spotykane dwoje dzieci z tego samego klucz

Replikowałem mój kod poniżej, ale z jakiegoś powodu CodePen nie pokazuje błędu.

var FilterOptions = React.createClass({ 
changeOption: function(type, e) { 
var val = e.target.value; 
this.props.changeOption(val, type); 
}, 

render: function() { 

return (
    <div className="filter-options"> 
    <div className="filter-option"> 
     <select id="product" name="Product" value={this.props.product} onChange={this.changeOption.bind(this, 'product')}> 
     <option value=''>Product</option> 
     {this.props.productOptions.map(function(option) { 
     return (<option key={option} value={option}>{option}</option>) 
     })} 
     </select> 
    </div> 
    </div> 
); 
} 
}); 

Codepen

jako pytanie wtórnym, jestem całkiem pewny, że moja resetu ma przywrócić Wartości wybranych pól, ale to też nie działa i po prostu resetowania świadczonych rezultaty - nie wiem, czy to jest związany z pierwszym problemem?

Każda pomoc bardzo doceniana

+0

Czy jesteś pewien, że 'ten.props.productOptions' ma unikalne wartości? Jeśli tak, to czy jesteś pewien, że ten kod podaje błąd, a nie gdzieś indziej? –

+0

@MartinMazzaDawson Nie, jest kilka zduplikowanych wartości we wszystkich wybranych menu - dokładny błąd wygląda tak samo - bundle.js: 9899 Ostrzeżenie: flattenChildren (...): Napotkano dwoje dzieci z tym samym kluczem, '1: $ prod3 '. Klucze podrzędne muszą być unikalne; gdy dwoje dzieci ma wspólny klucz, zostanie użyte tylko pierwsze dziecko. –

+2

Czy błąd zniknie, jeśli zmienisz "klucz" na wartość indeksu zamiast "opcji"? – azium

Odpowiedz

5

Dodanie indeksu jako wartości to rozwiązało. Dzięki @ Azium za sugestię.

<select id="product" name="Product" value={this.props.product} onChange={this.changeOption.bind(this, 'product')}> 
     <option value=''>Product</option> 
     {this.props.productOptions.map(function(option, value) { 
     return (<option key={value} value={option}>{option}</option>) 
     })} 
     </select> 
+0

To działa, uratowałeś mój dzień! –

+0

dziękuję, uratowałeś mój dzień –

14

Nie jest dobrym pomysłem użycie indeksu jako klucza. Klucz jest jedyną rzeczą używaną przez React do identyfikacji elementów DOM. Co się stanie, jeśli naciśniesz element na listę lub usuniesz coś w środku? Jeśli klucz jest taki sam jak wcześniej, React zakłada, że ​​element DOM reprezentuje ten sam komponent co poprzednio. Ale to już nie jest prawda. Od: https://medium.com/@robinpokorny/index-as-a-key-is-an-anti-pattern-e0349aece318

Znacznie lepiej użyć unikatowego ciągu z każdego elementu, który mapujesz jako klucz. Coś takiego jak <option key={value.id}> lub jeśli klucz nie istnieje, stwórz unikalny identyfikator, wykonując coś takiego jak <option key={value.name + value.description}>.

+0

Arrg, ale co, jeśli nie ma nic wyjątkowego w obiekcie rekwizytów? W moim przypadku mam wiersz z 5 polami wyboru. Pola wyboru są generowane dla każdego wpisu w tablicy. Ale nie ma w nich nic wyjątkowego ... – Kokodoko

+0

@Kokodoko Najlepiej byłoby użyć niezmiennych danych w tym przypadku (lub przynajmniej próbować nie systematycznie mutować swoich pól wyboru) i użyć skrótu obiektu jako klucza. To jedyny sposób na odróżnienie obiektów, takich jak punkty, pola wyboru itp., I utworzenie unikalnego klucza. –