-1

I have created a select usign react-select, with a button inside. I use this button to call another page in the api to obtain other 20 values.

 const [pageNumber, setPageNumber] = useState(0)

  useEffect(() => {
    props.getComunes(pageNumber);
  }, [pageNumber])

  const comunes = Comunes.map(comune => {
    return ({ value: comune.comCod, label: comune.comDes })
  })


  const addValue = () => {
    setPageNumber(pageNumber + 1)
  }


const SelectMenuButton = (props) => {
    console.log("props ", props)
    return (
      <components.MenuList  {...props}>
        {props.children}
        <button onClick={() => addValue()}>Add new element</button>
      </components.MenuList >
    )
  }

     return(
         //...
           <AvGroup>
                  <Label id="comCodLabel" for="comCod">
                     Select
                  </Label>
                  <AsyncSelect
                    options={comunes}
                    placeholder='Start typing'
                    components={{ MenuList: SelectMenuButton }} />
                </AvGroup>

      )

const mapDispatchToProps = {
  getComunes
}

Now my problem is that in this way the list is replaced with the new list ( so at the beginning I have 20 first values, if I click on button I have the second 20 values, while I would to obtain 40 result in the list ).

How can I do to concat the new list and not replace it?

Jack23
  • 1,368
  • 7
  • 32

1 Answers1

2

You can use the spread operator ... to append new values(set of values) to your existing values. I'd suggest you use another state which holds your option items. And every time you fetch new values, just append the new set of values to the state that holds all the items.

 const [pageNumber, setPageNumber] = useState(0)
 const [items,setItems] = useState([])
 const comunes = Comunes.map(comune => {
    return ({ value: comune.comCod, label: comune.comDes })
  })
 useEffect(() => {
    props.getComunes(pageNumber);
    setItems([...items,...comunes]) //Append comunes items to existing items.
  }, [pageNumber])


  const addValue = () => {
    setPageNumber(pageNumber + 1)
  }


const SelectMenuButton = (props) => {
    console.log("props ", props)
    return (
      <components.MenuList  {...props}>
        {props.children}
        <button onClick={() => addValue()}>Add new element</button>
      </components.MenuList >
    )
  }

     return(
         //...
           <AvGroup>
                  <Label id="comCodLabel" for="comCod">
                     Select
                  </Label>
                  <AsyncSelect
                    options={items} {/*Use state array items to populate options*/}
                    placeholder='Start typing'
                    components={{ MenuList: SelectMenuButton }} />
                </AvGroup>

      )

const mapDispatchToProps = {
  getComunes
}
Prajwal Kulkarni
  • 1,480
  • 13
  • 22
  • Thank you for your answer, I have a problem about options={items} {/*Use state array items to populate options*/} items results empty – Jack23 Oct 21 '21 at 09:21
  • It seems that comunes is empty at the beginning, if i click on the button in the select comunes is populated but iitems result like [Array(0)] – Jack23 Oct 21 '21 at 09:24
  • could you `console.log` comunes and check if it's containing an array of items? – Prajwal Kulkarni Oct 21 '21 at 09:30
  • Yes, at the beginning comunes is empty array, if i click on button it is populate of 20 items, if i click another time it is populated by other 20 items ( so there are only 20 elements and not 40) – Jack23 Oct 21 '21 at 09:32
  • If comunes is having an array of items, you should be able to append it to the previous 20 items, using `setItems([...items,...comunes])`, I've updated the same in the answer. Kindly verify and let me know if it's working. – Prajwal Kulkarni Oct 21 '21 at 09:38
  • Ok now it's at the beginning empty, if i click on the button it is populated, and if i click another time the other 20 result are appended – Jack23 Oct 21 '21 at 09:40
  • So basically, we're appending the values of the commune array to items each time the `useEffect` hook is invoked, i.e, each time `pageNumber` changes. That solves the issue right? Kindly consider marking the answer as accepted if it answered your question. Thanks. – Prajwal Kulkarni Oct 21 '21 at 10:01
  • Yes, and thank you for the answer. In your opinion there is a way to load the first 20 data at the beginning, without I should press button? – Jack23 Oct 21 '21 at 10:13
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/238388/discussion-between-prajwal-kulkarni-and-jack23). – Prajwal Kulkarni Oct 21 '21 at 10:16