0

For some reason my this.state call is not updating the state in my roleClicked function. I can't seem to figure out what the problem is. Here is the code:

import React, { Component } from 'react'
import { Redirect } from 'react-router-dom';
import instance from '../../../config/axios';
import ls from 'local-storage';
import Sidenav from '../../layout/Sidenav'
import isLoggedIn from '../../../helpers/isLoggedIn';
import redirectToLogin from '../../../helpers/redirectToLogin';
import apiErrorHandler from '../../../helpers/apiErrorHandler';
import RolesHeader from './RolesHeader';
import '../../../App.css'
import { Table, Pagination, Input, Alert } from 'antd';

export default class ViewRoles extends Component {

    state = {
        loggedIn: true,
        roleSelected: false, 
        roleSelectedId: null,
        rolesTable: {
            columns: null,
            dataSource: null,
            currentPageNumber: null,
            currentPageSize: null,
            total: null,
        },
        filters: {
            roleName: null
        },
        displays: {
            createRoleView: false,
            roleCreatedAlert: false,
        },
        errors: null
    }

    componentDidMount = () => {
      //here i make AJAX calls to set rolesTables
    } 

    roleClicked = (record) => {
        console.log("clicked")
        this.setState({
            roleSelected: true,
            roleSelectedId: record.key
        })
    }

    render() {

        if(this.state.roleSelected) {
            const roleUrl = "/roles/" + this.state.roleSelectedId
            return <Redirect to={roleUrl}/>
        }

        return (
            <React.Fragment>
                <Sidenav activeLink="roles"/>
                <Table 
                     className="border"
                     columns={this.state.rolesTable.columns} 
                     dataSource={this.state.rolesTable.dataSource} 
                     pagination={false}
                     onRow={(record) => {
                        return {
                           onClick: () => this.roleClicked(record)
                     }}}
                />
                <Pagination 
                    className="m-3"
                    current={this.state.rolesTable.currentPageNumber} 
                    pageSize={this.state.rolesTable.currentPageSize} 
                    total={this.state.rolesTable.total}
                    onChange={this.loadRolesTable}
                />
           </React.Fragment>)
    }
}

The function runs as expected but the state is not updated. Any idea what the problem could be?

Everywhere else I use this.setState it works. The full code can be found on this link.

Tobi Amira
  • 21
  • 4
  • Do you get any result when you invoke this function? Have you tried `console.log(this.state)` after the function call? – Evgenii Klepilin Feb 09 '20 at 11:48
  • Does `onRow` do the job properly? – Evgenii Klepilin Feb 09 '20 at 11:49
  • Check whether `record` get passed properly, and it is not undefined – Evgenii Klepilin Feb 09 '20 at 11:52
  • Also, in the code you linked above, you have `this.setState({ roleSelected: true, roleSelectedId: 1 })`, so no matter how many times you trigger that handler, it will always end up with the same result. Double check that whatever is being passed to `roleClicked` is correct. – goto Feb 09 '20 at 11:53
  • I suspect onRow isn't working properly – Chitova263 Feb 09 '20 at 12:03
  • @EvgeniiKlepilin yes I get the full state when I console.log(this.state) – Tobi Amira Feb 09 '20 at 12:10
  • Also, I get record when I console.log(record) as well. I set roleSelected to 1 while trying to debug just to see if something was wrong with record and it didn't work as well – Tobi Amira Feb 09 '20 at 12:11
  • I don't think it has to do with onRow. I put the same function in an onClick function on a div and it still didn't update the state. Additionally if I remove the declaration of `roleSelected` and `roleSelectedId` from the state the function works just fine and the state is updated. But if I have them defined as in the code it doesn't work. I can simply remove the declaration and move on but I'm quite interested in why it doesn't work. @chitova263 @goto @EvgeniiKlepilin – Tobi Amira Feb 09 '20 at 12:23
  • @EvgeniiKlepilin – Tobi Amira Feb 09 '20 at 13:18
  • Do you get console.log("clicked") back? –  Feb 09 '20 at 14:30
  • Yes I do @ProttayRudra – Tobi Amira Feb 09 '20 at 15:26

2 Answers2

1

I updated roleClicked to this and it works. I still have no idea why the initial code didn't work.

viewRole = async (record) => {
     var currentState = this.state;
     currentState.roleSelected = true;
     currentState.roleSelectedId = record.key;
     await this.setState(currentState);
     console.log(this.state)
} 

Just changing it to Async didn't work. Only assigning the state to currentState and then updating currentState and using it in setState worked. And now it works both synchronously and asynchronously.

Tobi Amira
  • 21
  • 4
0

try something like this

    this.setState(function(state, props) {
      return {
        ...state,
        roleSelected: true,
        roleSelectedId: record.key
           };
   });
iago-lito
  • 3,098
  • 3
  • 29
  • 54
briareus
  • 1
  • 1
  • I did this ```roleClicked = (record) => { console.log(record) this.setState((state, props) => { return { roleSelected: true, roleSelectedId: record.key} }) }``` still not working. – Tobi Amira Feb 09 '20 at 12:21