Jak umieścić element wewnątrz useState array React hook? Czy to stara metoda w stanie reagowania? Czy coś nowego?
Np. Przykład setState push ?
Jak umieścić element wewnątrz useState array React hook? Czy to stara metoda w stanie reagowania? Czy coś nowego?
Np. Przykład setState push ?
Odpowiedzi:
Kiedy używasz useState
, możesz uzyskać metodę aktualizacji dla elementu stanu:
const [theArray, setTheArray] = useState(initialArray);
wtedy, gdy chcesz dodać nowy element, używasz tej funkcji i przekazujesz nową tablicę lub funkcję, która utworzy nową tablicę. Zwykle to drugie, ponieważ aktualizacje stanu są asynchroniczne i czasami partiami:
setTheArray(oldArray => [...oldArray, newElement]);
Czasami możesz uciec bez korzystania z tego formularza wywołania zwrotnego, jeśli aktualizujesz tablicę tylko w programach obsługi dla pewnych określonych zdarzeń użytkownika, takich jak click
(ale nie podobne mousemove
):
setTheArray([...theArray, newElement]);
Zdarzenia, dla których React zapewnia, że renderowanie jest opróżnione, to „zdarzenia dyskretne” wymienione tutaj .
Przykład na żywo (przekazywanie wywołania zwrotnego do setTheArray
):
Ponieważ jedyną aktualizacją theArray
w tam jest ta w click
zdarzeniu (jedno z „dyskretnych” zdarzeń), mogę uciec z bezpośrednią aktualizacją w addEntry
:
useEffect
przykładzie ...?
useEffect
ma pustą listę zależności []
, zostanie wykonana tylko podczas pierwszego renderowania. Tak więc wartość theArray
wnętrza efektu zawsze będzie initialArray
. W sytuacjach, w których setTheArray([...initialArray, newElement])
nie miałoby to sensu, a theArray
stała zawsze będzie równa initialValue
, potrzebne są aktualizacje funkcjonalne.
setTheArray(()=>theArray.concat(newElement))
że zadziała, ale NIE! Ten parametr wywołania zwrotnego stanowi CAŁĄ RÓŻNICĘ.
Aby rozwinąć trochę dalej, oto kilka typowych przykładów. Począwszy od:
const [theArray, setTheArray] = useState(initialArray);
const [theObject, setTheObject] = useState(initialObject);
Wepchnij element na koniec tablicy
setTheArray(prevArray => [...prevArray, newValue])
Wypchnij / zaktualizuj element na końcu obiektu
setTheObject(prevState => ({ ...prevState, currentOrNewKey: newValue}));
Wypchnij / zaktualizuj element na końcu tablicy obiektów
setTheArray(prevState => [...prevState, {currentOrNewKey: newValue}]);
Wepchnij element na koniec obiektu tablic
let specificArrayInObject = theObject.array.slice();
specificArrayInObject.push(newValue);
const newObj = { ...theObject, [event.target.name]: specificArrayInObject };
theObject(newObj);
Oto kilka praktycznych przykładów. https://codesandbox.io/s/reacthooks-push-r991u
W ten sam sposób robisz to ze stanem „normalnym” w komponentach klasy React.
przykład:
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]);
to najprostsza odpowiedź, ale uważaj na mutacje elementów w tablicy . Użyj głębokiego klonowania elementów tablicy.
Najbardziej zalecaną metodą jest jednoczesne użycie funkcji opakowującej i operatora rozszerzania. Na przykład, jeśli zainicjowałeś stan nazwany w name
ten sposób,
const [names, setNames] = useState([])
Możesz wcisnąć do tej tablicy w ten sposób,
setNames(names => [...names, newName])
Mam nadzieję, że to pomoże.
jeśli chcesz naciskać po określonym indeksie, możesz zrobić, co poniżej:
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;
});
};
Możesz dołączyć tablicę danych na końcu stanu niestandardowego:
const [vehicleData, setVehicleData] = React.useState<any[]>([]);
setVehicleData(old => [...old, ...newArrayData]);
Na przykład, poniżej pojawia się przykład axios:
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]);
Wypróbowałem powyższe metody wypychania obiektu do tablicy obiektów w useState, ale podczas korzystania z TypeScript wystąpił następujący błąd :
Wpisz „TxBacklog [] | undefined 'musi mieć metodę' Symbol.iterator ', która zwraca iterator.ts (2488)
Konfiguracja tsconfig.json najwyraźniej była poprawna:
{
"compilerOptions": {
"target": "es6",
"lib": [
"dom",
"dom.iterable",
"esnext",
"es6",
],
To obejście rozwiązało problem (mój przykładowy kod):
Berło:
interface TxBacklog {
status: string,
txHash: string,
}
Zmienna stanu:
const [txBacklog, setTxBacklog] = React.useState<TxBacklog[]>();
Wypchnij nowy obiekt do tablicy:
// 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])
jeśli powyższe nie działa. Najprawdopodobniej wuseEffect(...theArray..., [])
, ważne jest, aby zdać sobie sprawę, żetheArray
jest to stała, więc aktualizacje funkcjonalne są potrzebne dla wartości z przyszłych renderów