Reputation: 463
I am building a datatable and have added a checkbox dropdown for adding/removing columns in the table. Everything works fine except it is not rerendering the table until I click on one of the header titles.
At the top of the function component, I am setting the state as follows:
const [formColumns, setDisplayFields] = useState(formFields);
formFields is retrieved from a file and is formatted as below. It's an array of JSON column objects that looks like this:
[id: {
name: 'id',
label: 'Patient Id',
displayColumn: false,
displayOrder: 1,
},
firstName: {
name: 'firstName',
label: 'First Name*',
requiredErrorMsg: 'First name is required',
displayColumn: true,
displayOrder: 2,
},
middleName: {
name: 'middleName',
label: 'Middle Name',
displayColumn: false,
displayOrder: 0,
},
lastName: {
name: 'lastName',
label: 'Last Name*',
requiredErrorMsg: 'Last name is required',
displayColumn: true,
displayOrder: 0,
},
suffix: {
name: 'suffix',
label: 'Suffix',
displayColumn: false,
displayOrder: 0,
},
dob: {
name: 'dob',
label: 'Date of Birth*',
requiredErrorMsg: 'Birth date is required',
invalidErrorMsg: 'This is not a valid date',
displayColumn: true,
displayOrder: 3,
},
organization: {
name: 'organization',
label: 'Organization',
displayColumn: false,
displayOrder: 4,
},
]
There are actually more columns, but this should suffice for describing what I'm doing. The 'displayColumn' element is changed in an onChange event in the same component that displays the table (passes it as a prop into checkbox menu). Here's the onchange:
/**
* handleCheckboxSelect
* @param {string} colname
*/
var handleCheckboxSelect = (colname) =>
{
//return the index of the column checked/unchecked
var icol = getColumnIndex(formColumns, colname);
console.log('FOUND COLINDEX = ' + icol + '.');
if (icol > -1) {
//toggle the display parameter
formColumns[icol].displayColumn = (formColumns[icol].displayColumn === false);
//store the updated column in the column list
setDisplayFields(formColumns);
}
else {
console.log('checkbox colname = ' + colname);
}
}
As you can see, I am using state as required, and any time state changes, it should force a re-render. However, it's not. Is it because I am using an array of objects? If I pass a single column back and stroe that in state, would that fix the issue? I'm stumped. Any help would be greatly appreciated!
Upvotes: 0
Views: 431
Reputation: 1147
You are setting same formColumns
reference on setDisplayFields
which will not trigger re-render of the component. Try to copy formColumns
to a new array and make changes on that array.
Try this -
var handleCheckboxSelect = (colname) =>
{
//create new array from existing one
let newColumns = [...formColumns];
var icol = getColumnIndex(newColumns, colname);
console.log('FOUND COLINDEX = ' + icol + '.');
if (icol > -1) {
//toggle the display parameter
newColumns[icol].displayColumn = (newColumns[icol].displayColumn === false);
//store the updated column in the column list
setDisplayFields(newColumns);
}
else {
console.log('checkbox colname = ' + colname);
}
}
Upvotes: 1