Martin Nordström
Martin Nordström

Reputation: 6025

Update state after an action has completed | React, Redux

My application pulls all of it's data from an API, it is basically a CRUD application. One of my actions is to delete an item from my list. Here's my action for it:

import axios from 'axios'

export function removeUser(userId, lockId) {
  return dispatch => {
    dispatch({ type: 'LOADING' })
    axios({
      method: 'post',
      url: 'http://192.168.100.105:7777/customer/removelockuser',
      data: {
        accessid: userId,
        lockid: lockId
      }
    })
      .then(res => {
        dispatch({ type: 'REMOVE_SUCCESS', payload: res.data })
      })
      .catch(err => {
        console.log('ERROR', err)
      })
  }
}

And in my component:

import React, { Component } from 'react'
import { connect } from 'react-redux'
import axios from 'axios'
import _ from 'lodash'
import moment from 'moment'
import { Row, Col, Grid } from 'react-bootstrap'
import { removeUser } from '../redux/actions/removeUserAction'

import '../userToLock.css'

class LockUsers extends Component {
  removeUser() {
    const userId = this.props.customer.userId
    const lockId = this.props.lockId
    //eslint-disable-next-line
    confirm('Vill du verkligen ta bort användaren?') &&
      this.props.removeUser(userId, lockId)
  }

  render() {
    const { user, customer, lockId } = this.props
    const time = moment(customer.timeframe.start).format(
      'MM/D [blev inbjuden klockan] HH:mm'
    )

    return (
      <Grid>
        <Row key={user._id}>
          <Col style={{ width: '100%' }}>
            <ul className="list">
              <li className="flex-container">
                <div className="flex-item-2">
                  <h5 className="sub-title-text-utl">
                    {customer.level == 0
                      ? <h5 className="users">
                          Inbjuden användare: {customer.email} <b>tillagd</b>:{time}
                        </h5>
                      : <h5 className="users">
                          Användare: {customer.name} {customer.surname} tillagd:{time}
                        </h5>}
                    <button className="remove-user-btn" onClick={() => this.removeUser(customer._id)}>
                      <span>&times;</span>
                    </button>
                  </h5>
                </div>
              </li>
            </ul>
          </Col>
        </Row>
      </Grid>
    )
  }
}

export default connect(null, { removeUser })(LockUsers)

This works absolutely fine, but if I want to see the changes I have to refresh my page. So I wonder if there's anyway to update the state when my action has completed. Maybe inside of my .then(), but I don't know if you can do that. This component is connected to my Redux store btw.

Really thankful for all the answers I can get!

Cheers!

Edit

One comment said that I should add my whole component, see my code above.

Upvotes: 0

Views: 1283

Answers (2)

Rowland
Rowland

Reputation: 1823

You can pass in the userId along with

dispatch({ type: 'REMOVE_SUCCESS', payload: res.data, userId })

Then in your reducer, you can filter it out from the array of users you've got.

case 'REMOVE_SUCCESS':
   return  [
     ...state, 
     users: state.users.filter(user => user.id != action.userId)
   ]

N.B: Never mutate state

Upvotes: 0

VF_
VF_

Reputation: 2653

Since you're passing user, customer, lockId from the parent component, the component in question will re-render once these props change.

Try something like this:

const { user, customer, lockId } = this.props;

return (
  {/* depending on what defines a user as deleted.. */}
  { user && user.id 
    ? ...
      <Row key={user._id}>
      ...
        {customer.level == 0
        ? <h5 className="users">
          Inbjuden användare: {customer.email} <b>tillagd</b>:{time}
          </h5>
        : <h5 className="users">
          Användare: {customer.name} {customer.surname} tillagd:{time}
          </h5>}
        <button className="remove-user-btn" onClick={() => this.removeUser(customer._id)}>
          <span>&times;</span>
        </button>
    ...
    : 'User not found / deleted'
  }
)

Upvotes: 1

Related Questions