useState array not updating correctly as it creates duplicate items

1.1k views Asked by At

I am trying to update the useState() array by passing through value of TextInput (onChangeText). The code is working fine however whenever I am clinking onPress (addBook function) it is updating/ adding previous text in the array not current one. So, to add current text I have to click button twice which is creating dupliate items in my array.

I may be making very studpid misatke but cant find it. Can any one help. Below is my entire code.

import React, { useState } from "react";
import { TextInput, View, Dimensions, TouchableOpacity } from "react-native";
import { MaterialCommunityIcons } from "@expo/vector-icons";
import { Entypo } from "@expo/vector-icons";

const screenHeight = Math.round(Dimensions.get("window").height);

const AddBookName = ({ hidePressed }) => {
  const [book, setBook] = useState();
  const [bookList, setBookList] = useState(["no name"]);

  const addBook = () => {
    setBookList([...bookList, book]);
    console.log(bookList);
  };

  return (
    <View style={{ flexDirection: "row" }}>
      <View style={{ flex: 1 }}>
        <TextInput
          style={{
            fontSize: 20,
            paddingVertical: 10,
            backgroundColor: "#ececec",
            paddingLeft: 10,
          }}
          placeholder="Enter the Book Name"
          placeholderTextColor="grey"
          // value={book}
          onChangeText={(text) => setBook(text)}
          type="text"
        ></TextInput>
      </View>

      <TouchableOpacity
        style={{
          flex: 0.15,
          backgroundColor: "green",
          alignItems: "center",
          justifyContent: "center",
        }}
        onPress={() => addBook()} 
      >
        <View>
          <MaterialCommunityIcons name="check" size={24} color="white" />
        </View>
      </TouchableOpacity>

      <TouchableOpacity
        style={{
          flex: 0.15,
          backgroundColor: "red",
          alignItems: "center",
          justifyContent: "center",
        }}
        onPress={hidePressed}
      >
        <View>
          <Entypo name="cross" size={24} color="white" />
        </View>
      </TouchableOpacity>
    </View>
  );
};

export default AddBookName;

enter image description here

2

There are 2 answers

0
Rajitha Udayanga On

Try to clean the previous input value after adding to the list.

  const addBook = () => {
    if (book) {
        setBookList([...bookList, book]);
        console.log(bookList);
        setBook("");
    }
  };
0
soloko On

This should remove duplicates:

const addBook = () => {
  setBookList(Array.from(new Set([...bookList, book])));
  console.log(bookList);
};

You could also store your booklist as a set instead of an array.