Обновить значения элемента массива

111
22 августа 2019, 19:30

Столкнулся с ошибкой при обновлении значения. Передаю значения, но стейт не обновляется. Ищу по переданному id. В итоге массив NewArr получает неверные данные

state = {
mobile : [
  {"id": 0, "name": "Dima", "phone": 12345},
  {"id": 1, "name": "Ira", "phone": 67890},
]
 saveItem = (name,phone,id) => {
let NewArr = this.state.mobile;
NewArr = NewArr.map(el => {
  if (el.id === id) {
    el.name = name;
    el.phone = phone
  }
  return NewArr;
})
this.setState({
  mobile: NewArr,
  read:false
})  

Пытаюсь обновить так, но не знаю как найти индекс NewMobile[index]. Скорее всего в filter, по как передать наружу не получается

    const newItem = {
  id: id,
  name: text,
  phone: phone
}
let NewArray = this.state.mobile.filter(el => el.id === id);
const a = this.state.mobile.indexOf(NewArray);
NewArray = newItem;
const NewMobile = this.state.mobile;
NewMobile[a] = NewArray;
this.setState({
  mobile: NewMobile
})
Answer 1
  1. Никогда не мутируйте состояние, нужно сделать копию массива, в идеале deep copy.
  2. Используйте деструктуризацию.
  3. Filter, map и т д создают новый массив на основании условий.. вам нужно записать новый элемент. То есть добавьте в мою реализацию просто условие, в котором проверяйте, есть ли в старом массиве id, если есть, то не добавляйте новый элемент, если нет, то добавляйте
  4. Название mobile не сильно хорошо отображает то, что оно хранит
  5. Лучше входным параметром в функцию saveMobile использовать объект, а не каждый параметр по отдельности. При использовании каждого параметра по отдельности велика вероятность перепутать порядок и вообще ошибиться

function App() { 
  return ( 
    <div className="App"> 
      <Some /> 
    </div> 
  ); 
} 
 
class Some extends React.Component { 
  state = { 
    phoneNumbers: [ 
      { 
        id: 0, 
        name: "Dima", 
        phone: 12345 
      }, 
      { 
        id: 1, 
        name: "Ira", 
        phone: 67890 
      } 
    ] 
  }; 
 
  saveMobile = obj => { 
    const { phoneNumbers } = this.state; 
    const clonePhoneNumbers = [...phoneNumbers]; 
    const contact = clonePhoneNumbers.find(mobile => mobile.id === obj.id); 
    if (contact) { 
      contact.name = obj.name; 
      contact.phone = obj.phone; 
    } else { 
      clonePhoneNumbers.push({ 
        id: obj.id, 
        name: obj.name, 
        phone: obj.phone 
      }); 
    } 
    this.setState(() => ({ 
      phoneNumbers: clonePhoneNumbers 
    })); 
  }; 
 
  renderMobileNumbers = mobiles => 
    mobiles.map(({ id, name, phone }) => ( 
      <div key={id}> 
        <p> id: {id} </p> 
        <p> name: {name} </p> 
        <p> phone: {phone} </p> 
      </div> 
    )); 
 
  render() { 
    const { phoneNumbers } = this.state; 
    return ( 
      <div> 
        {this.renderMobileNumbers(phoneNumbers)} 
        <button 
          onClick={() => 
            this.saveMobile({ id: 92, name: "vlad", phone: 2121321 }) 
          } 
        > 
          save 
        </button> 
        <button 
          onClick={() => 
            this.saveMobile({ id: 92, name: "eeee", phone: 2121321 }) 
          } 
        > 
          save 
        </button> 
      </div> 
    ); 
  } 
} 
 
// Render it 
ReactDOM.render(<App />, document.getElementById("root"));
<div id="root"></div> 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

READ ALSO
Можно ли посмотреть буфер обмена на JS?

Можно ли посмотреть буфер обмена на JS?

Задача суть задачи довольно простаНа сайте есть input, посетитель ставит в него курсор и потом нажимает Ctrl+V

87
Не правильное тело запроса axios.post

Не правильное тело запроса axios.post

Есть сервер на котором хранится база данныхЧерез постман делаю POST и в body указываю тип данных json, делаю запись типа "name":"John", "password":"123"и все нормально,...

93
Эмуляция timeout при получении файла

Эмуляция timeout при получении файла

Хотелось бы проверить правильность отработки ошибки timeout при загрузке по XHR файлаВ Chrome можно задать скорость загрузки/отдачи документа

84
Возвращение экрана в начало текста при нажатти кнопки &ldquo;Скрыть&rdquo;

Возвращение экрана в начало текста при нажатти кнопки “Скрыть”

Как мне сделать так, чтобы когда нажимаешь клавишу показать меньше текста, экран возвращался в начало текста? Код:

96