#javascript #reactjs #list #ecmascript-6 #react-props
#javascript #reactjs #Список #ecmascript-6 #react-реквизит
Вопрос:
Я пытаюсь ввести уникальные идентификаторы для элементов списка вместо использования индекса, но каждый метод, который я пробую, я, похоже, не могу заставить его работать в дочернем элементе. Это база, с которой я работаю. Я установил и импортировал import {v4 как uuidv4} из ‘uuid’; чтобы сделать это немного проще
Все, что вам нужно сделать, это просто ввести ‘uuidv4 ()’ для генерации случайного идентификатора
Родительский
import React from 'react';
import './App.css';
import ShoppingCartList from './ShoppingCartList'
import { v4 as uuidv4 } from 'uuid';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
shoppingCart: [],
newItem: '',
errorMessage: 'false',
};
this.onRemoveItem = this.onRemoveItem.bind(this);
}
handleChange = (e) => {
this.setState ({ newItem: e.target.value})
}
handleClickAdd = (e) => {
if(this.state.newItem === '') {
this.setState({errorMessage: 'true'});
} else {
return ( this.setState({ shoppingCart: this.state.shoppingCart.concat(this.state.newItem) }),
this.setState({newItem: ''}),
this.setState({errorMessage: 'false'})
)}
}
handleSubmit = (e) => {
e.preventDefault()
}
onRemoveItem = (i) => {
this.setState(state => {
const shoppingCart = state.shoppingCart.filter((item, j) => i !== j);
return {shoppingCart}
})}
render() {
return (
<div>
<form onSubmit ={this.handleSubmit}>
Shopping Cart Items
<br></br>
{ this.state.errorMessage === 'true' amp;amp;
<p className='error'> Please enter an item </p> }
<ul>
{this.state.shoppingCart.map((item, index,) => {
return <ShoppingCartList
item={item}
index={index}
onRemoveItem={this.onRemoveItem}
/>
})}
</ul>
<input
placeholder='Enter your item here'
value={this.state.newItem}
onChange={this.handleChange}
></input>
<button type='submit' onClick={this.handleClickAdd}>Add to Shopping list</button>
</form>
</div>
)
}
}
export default App;
Дочерний
[code]
import React from 'react';
function ShoppingCartList ({item,index, onRemoveItem}) {
return (
<li key={item}>{item} <button type="button" onClick={() => onRemoveItem(index)}>Delete</button></li>
)
}
export default ShoppingCartList;
Ответ №1:
Проблемы
Ключи React должны быть определены для отображаемого элемента / компонента, внутри дочернего компонента находится неправильное местоположение
Решение
- При добавлении товаров в корзину покупок генерируйте уникальный идентификатор при добавлении в состояние.
- Используйте идентификатор элемента в качестве ключа реакции в родительском элементе при сопоставлении элементов корзины и как способ идентификации элемента, который нужно удалить из корзины.
Обновите handleClickAdd
, чтобы создать новый объект item с идентификатором и значением. Перенесите существующий массив cart в новый массив и добавьте новый объект item в конец.
handleClickAdd = (e) => {
if (this.state.newItem === "") {
this.setState({ errorMessage: true });
} else {
this.setState((prevState) => ({
shoppingCart: [
...prevState.shoppingCart,
{
id: uuidv4(), // <-- new unique id
value: prevState.newItem // <-- item value
}
],
newItem: "",
errorMessage: false
}));
}
};
Обновите onRemoveItem
, чтобы использовать идентификатор для фильтрации.
onRemoveItem = (id) => {
this.setState((prevState) => ({
shoppingCart: prevState.shoppingCart.filter((item) => item.id !== id)
}));
};
Обновите свой рендеринг, чтобы добавить ключ react ShoppingCartList
.
{this.state.shoppingCart.map((item) => {
return (
<ShoppingCartList
item={item}
key={item.id}
onRemoveItem={this.onRemoveItem}
/>
);
})}
Обновите ShoppingCartList
, чтобы отобразить значение элемента и передать идентификатор элемента в обратный вызов remove item.
const ShoppingCartList = ({ item, onRemoveItem }) => (
<li>
{item.value}{" "}
<button type="button" onClick={() => onRemoveItem(item.id)}>
Delete
</button>
</li>
);