>

처음에는 다음과 같은 상태 구조가 있습니다 :

messages:[
        {id: 1, name: 'name1'},
        {id: 2, name: 'name2'}, ...
    ]

내가 원하는 것은 id 에 따라 하나의 메시지를 업데이트하는 것입니다.  키. 서버에서 다음과 같은 다른 객체를 얻습니다.

{id: 2, name: 'newName2'}

상태는 배열이다 : (2) [{…}, {…}] . 어떤 색인을 어떤 요소와 함께 업데이트해야할지 모르겠습니다. 객체 내부의 id 키만 알고 있습니다.

키 값을 기준으로 상태 내의 객체를 업데이트하는 방법은 무엇입니까?


  • 답변 # 1

    findIndex 를 사용할 수 있습니다  업데이트하려는 객체의 색인을 가져 와서 새 배열의 새 객체로 바꾸고 구성 요소 상태로 설정합니다.

    class App extends React.Component {
      state = {
        messages: [{ id: 1, name: "name1" }, { id: 2, name: "name2" }]
      };
      updateMessage(newMessage) {
        this.setState(prevState => {
          const messages = [...prevState.messages];
          const index = messages.findIndex(m => m.id === newMessage.id);
          messages[index] = newMessage;
          return { messages };
        });
      }
      render() {
        return (
          <div>
            {this.state.messages.map(message => (
              <div key={message.id}>{message.name}</div>
            ))}
            <button onClick={() => this.updateMessage({ id: 2, name: "newName2" })}>
              Update message
            </button>
          </div>
        );
      }
    }
    ReactDOM.render(<App />, document.getElementById("root"));
    
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
    <div id="root"></div>
    
    

  • 답변 # 2

    {key:'value'} 로 저장하는 것이 좋습니다.  키로 찾아야하는 경우 쌍입니다.

    몇 가지 옵션이 있습니다.

    키가 ID이고 색인과 일치하면 직접 액세스 할 수 있습니다.

    어레이 위로 반복

    [].find 사용

    목록을 개체로 변환하고 찾아보세요.

    지도 사용

    또는 findIndex

    .. etc

    <시간>
    let id = 1
    let message = messages [id -1];
    message.foo = 'bar';
    
    
    <시간>
    let prop = 'name', key = 'name1'
    for (const message of messages) if (message[prop] === key) message.foo = 'bar'
    
    
    <시간>
    const byProp = (prop,key) => ({[prop]:k}) => k == key
    const message = messages.find (byProp('name', 'name1'))
    
    
    <시간>
    const byProp = (arr,prop) => arr.reduce ((obj, itm) => ({...obj, [itm[prop]]:itm}),{})
    let message = byProp (messages, 'name')['name1']
    
    

  • 답변 # 3

    작동해야합니다

    const newMsg = { id: 10, message: 'hi' }
     this.setState(({ messages } => {
        return {
           ...messages.filter(x => x.id !== newMsg.id),
           newMsg
        }
     };
    
    

  • 답변 # 4

    Array.map 사용  배열을 수정하려면

    const messages = [
        {id: 1, name: 'name1'},
        {id: 2, name: 'name2'},
    ]
    const updateById = obj => {
      const { id } = obj;
      // here we check if new object has the same id as the old one
      // we replace old one with new
      return messages.map(message => message.id === id ? obj : message)
    }
    console.log(
      updateById({id: 1, name: 'newName'})
    )
    
    

  • 답변 # 5

    여러 가지 방법이 있습니다. 그중 하나가 아래와 같습니다.

    let x = [{id: 1, a: 1},{id: 2, b: 2}]
    let newO = {id: 2, b: 3}
    let y =[
        ...x.map(item => {
            if (item.id === newO.id) {
                return newO;
            } else return item
        })
    ]
    console.log(y)
    
    

관련 자료

  • 이전 gtk3 - glade를 사용하여 각 탭에 탭과 여러 개의 gtk 입력 필드가있는 노트북 설정
  • 다음 django - 인스턴스 모델의 속성이 변경되지 않는 이유