Як просунути елемент всередину масиву useState React? Це як старий метод у стані реакції? Або щось нове?
Наприклад, приклад pushState ?
Як просунути елемент всередину масиву useState React? Це як старий метод у стані реакції? Або щось нове?
Наприклад, приклад pushState ?
Відповіді:
Коли ви використовуєте useState
, ви можете отримати метод оновлення для елемента стану:
const [theArray, setTheArray] = useState(initialArray);
тоді, коли ви хочете додати новий елемент, ви використовуєте цю функцію і передаєте новий масив або функцію, яка створить новий масив. Зазвичай останні, оскільки оновлення стану є асинхронними, а іноді і пакетними:
setTheArray(oldArray => [...oldArray, newElement]);
Іноді ви можете обійтися без використання цієї форми зворотного виклику, якщо ви тільки оновити масив в обробниках для деяких конкретних користувальницьких подій , таких як click
(але не так, як mousemove
):
setTheArray([...theArray, newElement]);
Події, для яких React забезпечує змивання рендерингу, - це "дискретні події", перелічені тут .
Приклад у реальному часі (передача зворотного виклику в setTheArray
):
Оскільки єдиним оновленням є оновлення theArray
у click
події (одна з "дискретних" подій), я міг би піти від прямого оновлення в addEntry
:
useEffect
прикладі ...?
useEffect
містить порожній список залежностей []
, він буде виконаний лише під час першого візуалізації. Тож значення theArray
внутрішнього ефекту буде завжди initialArray
. У ситуаціях, коли setTheArray([...initialArray, newElement])
не має сенсу і коли theArray
константа завжди буде дорівнює, необхідні initialValue
функціональні оновлення.
setTheArray(()=>theArray.concat(newElement))
, спрацює, але НІ! Цей параметр зворотного виклику робить ВСЮ РІЗНИЦЮ.
Щоб розширити трохи далі, ось кілька типових прикладів. Починаючи з:
const [theArray, setTheArray] = useState(initialArray);
const [theObject, setTheObject] = useState(initialObject);
Натисніть елемент в кінці масиву
setTheArray(prevArray => [...prevArray, newValue])
Елемент push / update в кінці об'єкта
setTheObject(prevState => ({ ...prevState, currentOrNewKey: newValue}));
Елемент push / update в кінці масиву об'єктів
setTheArray(prevState => [...prevState, {currentOrNewKey: newValue}]);
Натисніть елемент в кінці об'єкта масивів
let specificArrayInObject = theObject.array.slice();
specificArrayInObject.push(newValue);
const newObj = { ...theObject, [event.target.name]: specificArrayInObject };
theObject(newObj);
Ось кілька робочих прикладів. https://codesandbox.io/s/reacthooks-push-r991u
Так само, як ви робите це з "нормальним" станом у компонентах класу React.
приклад:
function App() {
const [state, setState] = useState([]);
return (
<div>
<p>You clicked {state.join(" and ")}</p>
//destructuring
<button onClick={() => setState([...state, "again"])}>Click me</button>
//old way
<button onClick={() => setState(state.concat("again"))}>Click me</button>
</div>
);
}
// Save search term state to React Hooks with spread operator and wrapper function
// Using .concat(), no wrapper function (not recommended)
setSearches(searches.concat(query))
// Using .concat(), wrapper function (recommended)
setSearches(searches => searches.concat(query))
// Spread operator, no wrapper function (not recommended)
setSearches([...searches, query])
// Spread operator, wrapper function (recommended)
setSearches(searches => [...searches, query])
https://medium.com/javascript-in-plain-english/how-to-add-to-an-array-in-react-state-3d08ddb2e1dc
setTheArray([...theArray, newElement]);
- це найпростіша відповідь, але будьте обережні щодо мутації елементів у масиві . Використовуйте глибоке клонування елементів масиву.
Найбільш рекомендованим методом є використання функції обгортки та оператора поширення разом. Наприклад, якщо ви ініціалізували такий стан name
,
const [names, setNames] = useState([])
Ви можете натиснути на цей масив так,
setNames(names => [...names, newName])
Сподіваюся, що це допомагає.
якщо ви хочете натиснути на певний індекс, ви можете зробити, як показано нижче:
const handleAddAfterIndex = index => {
setTheArray(oldItems => {
const copyItems = [...oldItems];
const finalItems = [];
for (let i = 0; i < copyItems.length; i += 1) {
if (i === index) {
finalItems.push(copyItems[i]);
finalItems.push(newItem);
} else {
finalItems.push(copyItems[i]);
}
}
return finalItems;
});
};
Ви можете додати масив Даних в кінці нестандартного стану:
const [vehicleData, setVehicleData] = React.useState<any[]>([]);
setVehicleData(old => [...old, ...newArrayData]);
Наприклад, нижче ви з’ясуєте приклад аксіо:
useEffect(() => {
const fetchData = async () => {
const result = await axios(
{
url: `http://localhost:4000/api/vehicle?page=${page + 1}&pageSize=10`,
method: 'get',
}
);
setVehicleData(old => [...old, ...result.data.data]);
};
fetchData();
}, [page]);
Я спробував описані вище методи для введення об'єкта в масив об'єктів у useState, але при використанні TypeScript мала наступну помилку :
Введіть 'TxBacklog [] | undefined 'повинен мати метод' Symbol.iterator ', який повертає iterator.ts (2488)
Налаштування для tsconfig.json, мабуть, було правильним:
{
"compilerOptions": {
"target": "es6",
"lib": [
"dom",
"dom.iterable",
"esnext",
"es6",
],
Це обхідне рішення вирішило проблему (мій зразок коду):
Інтерфейс:
interface TxBacklog {
status: string,
txHash: string,
}
Змінна стану:
const [txBacklog, setTxBacklog] = React.useState<TxBacklog[]>();
Вставити новий об’єкт у масив:
// Define new object to be added
const newTx = {
txHash: '0x368eb7269eb88ba86..',
status: 'pending'
};
// Push new object into array
(txBacklog)
? setTxBacklog(prevState => [ ...prevState!, newTx ])
: setTxBacklog([newTx]);
setTheArray(currentArray => [...currentArray, newElement])
якщо вищезазначене не працює. Швидше за всеuseEffect(...theArray..., [])
, важливо розуміти, щоtheArray
це константа, тому для значень із майбутніх