ArchNoob
ArchNoob

Reputation: 4126

Redux state is being updated without dispatching any action

I should start off by saying this is not a duplicate of this question, which happened to have the same title.

I'm simply getting a customers object of arrays from props inside a componentDidMount method like this;

  componentDidMount() {
      const { customers } = this.props
      const expiringCustomers = getExpiringCustomers(customers)
      console.log('Expiring customers ', expiringCustomers)
  }

Inside another file, I have that getExpiringCustomers function which takes the customers passed and is suppose to return a newly modified list of customers like this;

function numbersOnly(value) {
    if(_.isString(value)) {
        value = Number(value.replace(/[^\d]/g, ''))
    }

    return value
}

function normalizeNumber(collection, field) {
    return collection.map(obj => {
        obj[field] = numbersOnly(obj[field])
        return obj
    })
}


export function getExpiringCustomers(customers) {
    const expiringCustomers = customers.filter(customer => {
        const daysLeft = Number(new Date(customer.endDate)) - _.now()
        if(daysLeft <= (dateInMonth * 3)) {
            return customer
        }
    })

    return normalizeNumber(expiringCustomers, 'rent')
}

I'm connecting my react component with redux state like this;

const mapStateToProps = state => ({
    customers: state.customers.filter(customer => customer && !customer.deleted)
})

export default connect(mapStateToProps)(Accounting)

Problem

After the functions run and log results, customers' state is changed in redux store.

This is very confusing as customers_edit action has to pass through some procedures but none of them are called/logged.

Snapshot of the affected object:

Ps. The data is just boilerplate.

//- Focus on rent property

const customers = [
...,
{
      id: 'o91wukyfsq36qidkld02a0voo93rna5w',
      cardId: 'GD-1101010111',
      id_type: 'Driving License',
      firstName: 'Maalim',
      lastName: 'Guruguja',
      names: 'Maalim Guruguja',
      property: '5iaprurefg3v3uhad688mypo9kqf6xk3',
      rent: '250,000',
      email: '[email protected]',
      phone: '239-288-3838-38',
      noticePeriod: '3',
      status: '2 months remain',
      startDate: '2018-07-09',
      endDate: '2018-08-17',
      createdAt: 1530623480772,
      updatedAt: 1531213159147
    },
    ...
]

//- After the functions run, log and edit customers array
const customers = [
...,
{
      id: 'o91wukyfsq36qidkld02a0voo93rna5w',
      cardId: 'GD-1101010111',
      id_type: 'Driving License',
      firstName: 'Maalim',
      lastName: 'Guruguja',
      names: 'Maalim Guruguja',
      property: '5iaprurefg3v3uhad688mypo9kqf6xk3',
      rent: 250000,
      email: '[email protected]',
      phone: '239-288-3838-38',
      noticePeriod: '3',
      status: '2 months remain',
      startDate: '2018-07-09',
      endDate: '2018-08-17',
      createdAt: 1530623480772,
      updatedAt: 1531213159147
    },
    ...
]

From the linked question (possible duplicate one) the guy who answered stated that it's some mutation issue that may cause this. I'm not sure if that applies on props that are suppose to be read-only.

How can I stop these functions from updating my redux store, please help.

Upvotes: 8

Views: 2742

Answers (2)

Ori Drori
Ori Drori

Reputation: 191976

You mutate the objects in normalizeNumber, since all the array methods you use don't clone the array's objects.

Change normalizeNumber callback to return a new object with the updated field:

function normalizeNumber(collection, field) {
    return collection.map(obj => ({
        ...obj,
        [field]: numbersOnly(obj[field])
    }))
}

Upvotes: 5

Colin Ricardo
Colin Ricardo

Reputation: 17249

It looks like you're modifying the customers array unintentionally.

Try:

componentDidMount() {
      const { customers } = { ...this.props };
      const expiringCustomers = getExpiringCustomers(customers)
      console.log('Expiring customers ', expiringCustomers)
  }

Upvotes: 0

Related Questions