Я считаю, что items.concat([children])
создает новые компоненты, поэтому вам также нужно будет передавать методы move()
и delete()
в качестве обратных вызовов (или передавать элементы в качестве аргумента). Кроме того, items.concat([children])
копирует старые компоненты (включая реквизиты в их начальных значениях) и переводит их в состояние, таким образом, только последний элемент получает конечное состояние (фактически его вероятный позади, то есть ваш первый элемент). рендерингу передается пустой массив this.state.items
, поскольку он еще не включит себя, так как состояние устанавливается после создания).
Возможно, попробуйте либо преобразовать в компонент на основе классов, который позволит вам явно указывать привязку this
, либо использовать метод типа renderItems
для создания содержимого без создания новых компонентов (показано в моем фрагменте ниже)
Также:
- Избегайте мутирования массива состояний с [... items], где это необходимо.
- Требуется динамически генерируемый контент (например, с циклом или картой)иметь уникальную ключевую опору для каждого сгенерированного предмета. Здесь я использовал
Math.random()
(который может не подходить для производства) - Вы должны проверить
futureIndex < items.length
Я создал рабочий упрощенный / переработанный пример в JSX, которыйможет помочь вам добраться туда, куда вам нужно идти
ОБНОВЛЕННЫЙ фрагмент кода с использованием renderItems
const PriorizationList = () => {
const [items, setItems] = React.useState([]);
const move = (currentIndex, futureIndex) => {
if (futureIndex !== -1 && futureIndex < items.length ) {
const tempItemsAray = [...items]
const item = tempItemsAray[currentIndex];
const movingItem = tempItemsAray[futureIndex];
tempItemsAray[currentIndex] = movingItem;
tempItemsAray[futureIndex] = item;
setItems(tempItemsAray);
}
};
const deleteItem = (index) => {
setItems(prevItems => prevItems.filter((_,i) => i !== index));
};
const addItem = () => {
const id = String(Math.floor(Math.random() * 100000))
const newItems = [...items , { id }];
setItems(newItems);
};
const renderItems = () => {
return items.map((item, index) => {
return (
<div>
<div>
<span>Item: {item.id}</span>
<button type="pushUp" onClick={() => move(index, index - 1)} >up</button>
<button type="pushDown" onClick={() => move(index, index + 1)} >down</button>
<button type="delete" onClick={() => deleteItem(index)} >delete</button>
</div>
</div>
);
})
}
return (
<div>
<button type="text" onClick={addItem} > Add </button>
{renderItems()}
</div>
);
};
ReactDOM.render(
<PriorizationList />,
document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="react"></div>
Предыдущий фрагмент передачи с обратными вызовами
const PriorizationList = () => {
const [items, setItems] = React.useState([]);
const move = (currentIndex, futureIndex) => {
if (futureIndex !== -1 && futureIndex < items.length ) {
const tempItemsAray = [...items]
const item = tempItemsAray[currentIndex];
const movingItem = tempItemsAray[futureIndex];
tempItemsAray[currentIndex] = movingItem;
tempItemsAray[futureIndex] = item;
setItems(tempItemsAray);
}
};
const deleteItem = (index) => {
setItems(prevItems => prevItems.filter((_,i) => i !== index));
};
const addItem = () => {
const id = String(Math.floor(Math.random() * 100000))
const newItems = [...items , { id , jsx : LineItemJSX }];
setItems(newItems);
};
const LineItemJSX = ({deleteItem , move , index , item}) => {
return (
<div>
<span>Item: {item.id}</span>
<button type="pushUp" onClick={() => move(index, index - 1)} >up</button>
<button type="pushDown" onClick={() => move(index, index + 1)} >down</button>
<button type="delete" onClick={() => deleteItem(index)} >delete</button>
</div>
)
}
return (
<div>
<button type="text" onClick={addItem} > Add </button>
{items.map((item, index) => {
const Component = item.jsx
return (
<Component index={index} key={item.id} deleteItem={deleteItem} move={move} item={item}/>
);
})}
</div>
);
};
ReactDOM.render(
<PriorizationList />,
document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="react"></div>
Предыдущий фрагмент, проходящий с элементами, указывается в виде проп const PriorizationList = () => {
const [items, setItems] = React.useState([]);
const move = (items , currentIndex, futureIndex) => {
if (futureIndex !== -1 && futureIndex < items.length ) {
const tempItemsAray = [...items]
const item = tempItemsAray[currentIndex];
const movingItem = tempItemsAray[futureIndex];
tempItemsAray[currentIndex] = movingItem;
tempItemsAray[futureIndex] = item;
setItems(tempItemsAray);
}
};
const deleteItem = (index) => {
setItems(prevItems => prevItems.filter((_,i) => i !== index));
};
const addItem = () => {
const id = String(Math.floor(Math.random() * 100000))
const newItems = [...items , { id , jsx : LineItemJSX }];
setItems(newItems);
};
const LineItemJSX = ({items , index , item}) => {
return (
<div>
<span>Item: {item.id}</span>
<button type="pushUp" onClick={() => move(items ,index, index - 1)} >up</button>
<button type="pushDown" onClick={() => move(items ,index, index + 1)} >down</button>
<button type="delete" onClick={() => deleteItem(index)} >delete</button>
</div>
)
}
return (
<div>
<button type="text" onClick={addItem} > Add </button>
{items.map((item, index) => {
const Component = item.jsx
return (
<Component index={index} key={item.id} item={item} items={items}/>
);
})}
</div>
);
};
ReactDOM.render(
<PriorizationList />,
document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="react"></div>