View is not updated when data changes, React,js

I am new to react, I am programming the function onAdd(), when I call that it should add the item to state and then I update the hook with the new item setBooks(state).

const state = {
  books: [
    { id: 0, rating: 4, title: "Harry Potter y el cáliz de fuego", image: "libro01.jpg"},
    { id: 1, rating: 3, title: "The shining", image: "libro02.jpg" },
    { id: 2, rating: 5, title: "Código Da Vinci", image: "libro03.jpg" },
    { id: 3, rating: 5, title: "El principito", image: "libro04.jpg" },
    { id: 4, rating: 5, title: "Sobrenatural", image: "libro05.jpg" },
  ],
  copyBooks: []
};

function App() {

  const [books, setBooks] = useState(state);

  const onAdd = (item)=>{
    //add new item to books
    console.log('Add: ', item);
    const id = state.books[state.books.length-1].id++;
    item['id'] = id;
    state.books.push(item);
    setBooks(state);
  }

  return (
    <div className="App">
      <Menu onadd={onAdd}/>
      <List items={books.books}/>
    </div>
  );
}

this works fine internally, I print the books object and it is up to date. When I try to print the data of the child <List /> component is not printed, until I make a change on the server and it is updated. I came to the conclusion that the problem is that the List component <List /> is not refreshed.

books refers to hooks and books.books to the data.

I do not know how I can solve it, I know it is something basic but I am starting in this technology.

Upvotes: 1

Views: 27

Answers (1)

Nick
Nick

Reputation: 16576

Your onAdd function is mutating state, meaning React sees the same object reference as before and will not update. To make sure an update happens, copy the array and set the state to the new copy:

const onAdd = (item) => {
  //add new item to books
  console.log('Add: ', item);
  const id = state.books[state.books.length-1].id + 1;
  item['id'] = id;
  const newBooks = [...state.books, item];
  setBooks({ ...state, books: newBooks });
}

Edit: by the way, I might recommend some less confusing terminology when naming variables. The local books variable actually refers to the entire state and then books.books refers to the actual books... that's going to cause mistakes because it's very confusing.

Upvotes: 1

Related Questions