React Hooks (useState)의 푸시 방법?


답변:


312

를 사용 useState하면 상태 항목에 대한 업데이트 메서드를 가져올 수 있습니다.

const [theArray, setTheArray] = useState(initialArray);

그런 다음 새 요소를 추가하려는 경우 해당 함수를 사용하고 새 배열 또는 새 배열을 생성 할 함수를 전달합니다. 일반적으로 후자는 상태 업데이트가 비동기적이고 때로는 일괄 처리되기 때문입니다.

setTheArray(oldArray => [...oldArray, newElement]);

당신이 경우 때때로 당신은, 그 콜백 양식을 사용하지 않고 멀리 얻을 수 있습니다 같은 특정 특정 사용자 이벤트 핸들러의 배열을 갱신 click(하지만 같은 mousemove) :

setTheArray([...theArray, newElement]);

React가 렌더링이 플러시되도록 보장하는 이벤트는 여기에 나열된 "이산 이벤트" 입니다.

라이브 예제 (에 콜백 전달 setTheArray) :

에 대한 유일한 업데이트 theArrayclick이벤트에 하나 ( "이산"이벤트 중 하나) 이기 때문에 다음 에서 직접 업데이트 할 수 있습니다 addEntry.


1
... setTheArray(currentArray => [...currentArray, newElement])위의 방법이 작동하지 않으면 시도 하십시오. 대부분의 경우에서 상수 useEffect(...theArray..., [])임을 인식하는 theArray것이 중요 하므로 향후 렌더링의 값에 대해 기능적 업데이트 가 필요합니다
Aprillion

@Aprillion-그 useEffect예에서 무슨 말을하는지 잘 모르겠습니다 ...?
TJ Crowder

1
(가) 경우 useEffect빈 의존성 목록을 가지고 [], 그것은 단지 첫 렌더링하는 동안 실행됩니다. 따라서 theArray효과 내부 의 값 은 항상입니다 initialArray. setTheArray([...initialArray, newElement])말이 안되는 상황에서 theArray상수가 항상 initialValue이면 기능 업데이트가 필요합니다.
Aprillion

@Aprillion-나는 아직도 그것을 얻지 못하고, 아마도 약간 조밀 할 수 있습니다. :-) 왜 초기 배열 값으로 효과가 필요 합니까? (내 말은, 드물게 사용 사례가있을 수 있지만 ...) 그렇게하더라도 질문과 무슨 관련이 있습니까?
TJ Crowder

1
야, 나는 이것으로 가장 오랫동안 고생했다. 나는 setTheArray(()=>theArray.concat(newElement))작동 할 것이라고 생각 했지만, 아니! 콜백에 대한 해당 매개 변수는 모든 차이를 만듭니다.
Jeff Lowery

52

좀 더 확장하기 위해 다음은 몇 가지 일반적인 예입니다. 로 시작:

const [theArray, setTheArray] = useState(initialArray);
const [theObject, setTheObject] = useState(initialObject);

배열 끝에서 요소 푸시

setTheArray(prevArray => [...prevArray, newValue])

개체 끝에서 요소 푸시 / 업데이트

setTheObject(prevState => ({ ...prevState, currentOrNewKey: newValue}));

객체 배열 끝에서 요소 푸시 / 업데이트

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


5
모든 예를 들어 주셔서 감사합니다. 내가 문제가 있었던 정확한 것은 배열 객체의 끝에있는 Push 요소였습니다 . 여러 가지 시도를 해봤지만 함께 할 수는 없었습니다.
sdouble

1
prevState를 사용하면 동시 배열 연결 및 필터에 마지막 호출 만 적용되는 문제가 해결되었습니다.
Henrique Bruno

5

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

1
이 온 클릭으로 작동하지만 setState를은 (oldstate가 =>는 [... oldstate가이 pushsomething은]) 당신이 그것을 할 방법입니다
사이러스 Zei

3
// 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


2

setTheArray([...theArray, newElement]);가장 간단한 대답이지만 theArray 항목의 변형에주의하십시오 . 배열 항목의 전체 복제를 사용합니다.


언급 한 딥 클로닝은 objA로 수신한다는 의미입니까? UseState를 사용하고 objA를 objB와 연결 하시겠습니까? 이 링크와 동일합니까? gist.githubusercontent.com/kahsing/…
Luiey

1

가장 권장되는 방법은 래퍼 함수와 분산 연산자를 함께 사용하는 것입니다. 예를 들어 다음 name과 같은 상태를 초기화 한 경우

const [names, setNames] = useState([])

다음과 같이이 배열에 푸시 할 수 있습니다.

setNames(names => [...names, newName])

도움이 되었기를 바랍니다.


1
링크 전용 답변을 게시하지 마십시오. 링크는 나중에 끊어 질 수 있습니다. 대신 해당 기사에 대한 글을 작성하고 실제로 질문에 답하십시오.
BlackCetha

이 링크가 질문에 답할 수 있지만 여기에 답변의 필수 부분을 포함하고 참조 용 링크를 제공하는 것이 좋습니다. 링크 된 페이지가 변경되면 링크 전용 답변이 무효화 될 수 있습니다. - 리뷰에서
ilke444

1

특정 인덱스 이후에 푸시하려면 다음과 같이 할 수 있습니다.

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

1

사용자 지정 상태 끝에 데이터 배열을 추가 할 수 있습니다.

  const [vehicleData, setVehicleData] = React.useState<any[]>([]);
  setVehicleData(old => [...old, ...newArrayData]);

예를 들어, 아래에 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]);

0

useState의 개체 배열에 개체를 푸시하기 위해 위의 방법을 시도했지만 TypeScript를 사용할 때 다음 오류가 발생 했습니다 .

유형 'TxBacklog [] | undefined '에는 iterator를 반환하는'Symbol.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]);
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.