>

저녁 식사 테이블에 손님을 배정 할 수있는 테이블 플래너 앱을 만들고 있습니다. tabledata라는 상태로 객체 배열을 만들었습니다. 여기에는 다음과 같은 객체가 포함됩니다.

   this.state = {
      tabledata: [
        {
          name: "Top Table",
          guests: ["guest1", "guest2", "guest3"]
        },
        {
          name: "Table One",
          guests: ["guest3", "guest4", "guest5"]
        }
      ]
    }

그런 다음 손님이 테이블 사이를 이동할 수있는 드래그 앤 드롭 인터페이스를 만들고 있습니다. 다음과 같이 상태를 업데이트하려고 시도했습니다.

 updateTableList (tablename, guest) {
    const selectedTableObj = this.state.tabledata.filter((tableObj) => tableObj.name === tablename);
    const otherTableObjs = this.state.tabledata.filter((tableObj) => tableObj.name !== tablename);
    selectedTableObj[0].guests.push(guest);
    const updatedObjectArray = [...otherTableObjs, selectedTableObj];
    this.setState({
      tabledata: [...otherTableObjs, ...selectedTableObj]
    });
  }

이것은 작동하지만 state에서 selectedTableObj를 제거하고 배열의 끝에 추가했기 때문에 화면에 펑키 한 결과가 나타납니다. 업데이트 된 테이블은 항상 예상대로 페이지의 맨 아래로 이동합니다.

어레이 내에서 위치를 변경하지 않고 어떻게 객체를 업데이트 할 수 있습니까?


  • 답변 # 1

    Array.findIndex() 를 사용하여 업데이트하려는 테이블의 인덱스를 찾으십시오. . 새로운 tabledata 만들기  정렬. Array.slice() 사용  업데이트 된 테이블 전후에 항목을 가져 와서 새로운 tabledata 에 확산시킵니다.  정렬. 오브젝트 스프레드를 사용하여 새 테이블 오브젝트를 작성하고 업데이트 된 guests 를 추가하십시오.  배열하고 이전 항목 사이에 테이블 객체를 추가하십시오.

    코드 (테스트되지 않음) :

    updateTableList(tablename, guest) {
      this.setState((prevState) => {
        const tableData = prevState.tabledata;
        const selectedTableIndex = tableData.findIndex((tableObj) => tableObj.name === tablename);
        const updatedTable = tableData[selectedTableIndex];
        return {
          tabledata: [
            ...prevState.tabledata.slice(0, selectedTableIndex),
            {
              ...updatedTable,
              guests: [...updatedTable.guests, guest]
            },
            ...prevState.tabledata.slice(selectedTableIndex + 1)
          ]
        };
      });
    }
    
    

  • 답변 # 2

    selectedTableObj[0].guests.push(guest)  React에서 권장하지 않는 상태를 직접 변경합니다.

    이것을 시도하십시오 :

    this.setState((prevState) => {
      const newData = [...prevState.tabledata];
      // if you pass in `index` as argument instead of `tablename` then this will not be needed
      const index = prevState.tabledata.findIndex(table => tableObj.name === tablename); 
      newData[index] = {
        ...newData[index],
        guests: newData[index].guests.concat([guest]),
      };
      return { tabledata: newData };
    });
    
    

    이전 테이블에서 게스트를 제거하지 않았으므로 해당 게스트를 수정해야합니다.

  • 답변 # 3

    Array.reduce로 수행 할 수 있습니다

    let newState = this.state
    // let newState = {...this.state} // in case you want everything immutable
    newState.tableData = newState.tableData.reduce((acc, table) => 
      if(table.name === tableName) {
        return acc.concat({...table, guests: table.guests.concat(newGuest)})
      } else {
        return acc.concat(table)
      }
    )
    
    

관련 자료

  • 이전 MS Access 쿼리가 잘못 표시됩니다
  • 다음 문자열 형식의 값으로 구성된 사전 파이썬에서 가장 작은 값을 가진 키 찾기