I am using the checkbox to determine the value and trying to push the value to the current component's state, but there is only one value can be pushed into the array in the state, I can't figure out exactly what caused this.

I am building a search bar and a result list. When the user input some data in the search bar, then the result list will display the result that related to the input data, then the user can select the multiple items to the state, then I can pass the data in the state array to the backend database. I have done the search bar part, but when I trying to map the value in the checkbox to state array, the state array always displays a value when I selected multiple items.

this is CustomerSMS component:

import React, { Component } from "react";
import { connect } from "react-redux";
import { firestoreConnect } from 'react-redux-firebase'
import { compose } from 'redux'
import FilteredCustomerList from './FilteredCustomerList'
class CustomerSMS extends Component {
    state ={
        search:null
    }

    handleChange = (e) => {
        this.setState({
            ...this.state,
            search:e.target.value
        })
    }
    render() {

        const { customers } = this.props;

        return(
            <div className="customerSMS container">

                    <p>search bar here</p>
                    <input type="text" id="search-string" onChange= 
 {this.handleChange}></input>                   
                <FilteredCustomerList customers={customers} search={this.state.search}/>
                <p>send message box here</p>
            </div>
        )
    }
}
const mapStateToProps = (state) => {
    // console.log(state);
    return{
        customers:state.firestore.ordered.customers
    }
}
export default compose(
    connect(mapStateToProps),
    firestoreConnect([
        {collection:'customers'}
    ])
)(CustomerSMS)

this is the FilteredCustomerList component:

import React from 'react'
import CustomerSummary from './CustomerSummary';


const FilteredCustomerList = ({customers, search}) => {
    // console.log(search);
    return (
    <div className="customer-list">
        <ul>
            { customers && customers.map( customer => {
                return (
                    <CustomerSummary customer={customer} key={customer.id} search={search}/>
                )
            }

            )}
        </ul>
    </div>
    )
}
export default FilteredCustomerList

This is the component included the checkbox:

import React, { Component }  from 'react'
class CustomerSummary extends Component {
state = {
    phonenumberList:[]
}

handleChange = (e) => {
    let phonenumberList = this.state.phonenumberList;
    console.log(e.target.checked);
    console.log(e.target.value);
    let index

    if(e.target.checked){
        phonenumberList.push(e.target.value)

    }else{
        index = phonenumberList.indexOf(e.target.value)
        phonenumberList.splice(index, 1)
    }
    console.log(phonenumberList);
}

render(){
    // console.log(this.props);
    console.log(this.state);
    if(this.props.customer.location === this.props.search){
     return (
         <div>
             <li>
                <input 
                type="checkbox" 
                name="phonenumber"
                value={this.props.customer.phonenumber} 
                onChange={this.handleChange} 
                />
                {this.props.customer.fullname} {this.props.customer.location}
            </li>

         </div>
     )

 }else{
     return null
 }
}
}
export default CustomerSummary

I expect phonenumberlist in the state should be [number1, number2, number3...] when I selected number1 & number2 & number3 ...., but the actual output is [number1] when I selected number1, and the output is [number2] when I selected number1 & number2, or the output is [number3] when I selected number1 & number2 $ number3, it always pushes the last one I selected value, I am stuck here for a long time, if anyone can help me, I will be very grateful.

2 Answers

0
Fotoncito On

You don't have to do this. Remove the ...this.state part

handleChange = (e) => {
    this.setState({
        ...this.state,
        search:e.target.value
    })
}

When pushing to a array you use the spread operator as such:

this.setState(prevState => ({
  myArr: [ ...prevState.myArr, newElement]
}))
1
Dynatropik On

If you want to update phonenumberList in your state, you have to call this.setState({phonenumberList: yourValue}) minimally.

What you are doing now when a checkbox is clicked is: let phonenumberList = this.state.phonenumberList; that is assigning the current value of this.state.phonenumberList (that is []) to a newly created phonenumberList.

Then you add the checked value, and console.log phonenumberList.

Your state get never updated, so at each click you start again with the empty array.