Проект React ToDoList — уникальные идентификаторы

#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>
  );
  

Редактировать react-todolist-project-unique-ids