Ant-Design Table not rendering when change state in mobx store - reactjs

I program the behavior of clicking on a row in the ant design Table component. This should change the rowClassName on the Table. Here is an example on CodeSendBox. When you click on a table row, the value in the Store.selectedRowKey changes, but the table is not re rendering. If you move the dividing slider to the sandbox and the table size changes, then rendering occurs and a new row selection is applied
Here's another example, where mobx don't work with ant-design Table
Ant Design Table with Modal form CRUD
I'm new in the Mobx
I really want to understand what I'm doing wrong

To re-render an Ant-Design table, you have to pass the data-source value as a clone of the observable value.
you have to change
<Table
columns={columns}
dataSource={values}
/>
to the following code:
<Table
columns={columns}
dataSource={[...values]}
/>

Basically you don't use selectedRowKey inside your observer component, so that's why it does not rerender when it changes.
You pass a callback function to a Table but Table is not observer.
I am not sure if it possible to make it observer in antd, but what else you can do:
1) Just use selectedRowKey inside your render somewhere. Like just console.log it and then your whole component will rerender (including the Table) when row is clicked.
Or better way, mix it with data rows, for example add isSelected key for each data for inside render and change rowClassName to use this flag:
dataSource={data.map(item => ({...item, isSelected: this.props.Store.selectedRowKey === item.key}))}
rowClassName={x => x.isSelected ? 'test-table-row-selected' : ''}
2) Use antd rowSelection prop like that rowSelection={{selectedRowKeys: [selectedRowKey]}}. But it will also add checkboxes to each row.

I can imagine that people are still looking for answers specially with the newest version of antd.
So in Antd version 5.x table API, you could find a property call rowKey.
In version 4.0 table API, the property called key thou.
And to way to tackle the problem correctly is to set it like following:
<Table
columns={columns}
dataSource={data}
rowKey={data.key} />
Note: Please consider to have a key property in your array of course. key must be unique.

Related

React IonSelect not rendering pre selected value from state

I'm stuck on the following issue from a project I have taken over. I have a page that has a component with an IonSelect. The options of the select are loaded from data obtained from a server and set in the state whilst being passed as a prop to the select, There is also a user object being loaded that contains a value that should be used as a pre selected value. The IonSelect doesn't show the pre selected text value when screen loads. If I click the IonSelect then the selected value shows. I tried a timeout to see if the render was happening before the data is loaded but it makes no difference. This question here shows the same problem but for an angular app. Is there something similar I can do for react?
The previous dev was new to react so I'm trying to refactor some code for efficiency and readability. Is there any advice that can be offered without code being uploaded? Currently, select is in a 5th child component and is using prop drilling to pass the data down.
Update: please see some of the code I've managed to pull for this issue.
I have tried using a standard html select and the pre selected value shows fine, so the problem is maybe within the IonSelect element or its wrapper? I have also tried overriding the compare to function of the select as explained in the docs. No joy. I've spent too many hours trying to solve this to no avail.
<IonItem className="statusField">
<IonLabel position="stacked">Job Status</IonLabel>
<IonSelect
id="jobStatus"
value={props.theJob.jobStatus!.toString()}
style={{color: getStatusColour(props.theJob.jobStatus)}}
interface="popover"
onIonChange={(e) => {
console.log("the value")
//document.getElementById("jobStatus")!.style.color = getStatusColour(parseInt((document.getElementById("jobStatus") as HTMLInputElement).value));
props.switchCancel();
props.setDirtyFlag(true);
}}>
{props.theJob.jobStatus && props.jobStatuses?.map((jobStatus, i) =>{
return<IonSelectOption
key={`Jstat ${i}${jobStatus.recordID}`}
value={jobStatus.recordID.toString()}
>
{jobStatus.summaryStatus.toString()}</IonSelectOption>
})}
</IonSelect>
</IonItem>
UPDATE
I think I've got it going. I had to do the following but it now renders the pre-selected value on screen refresh and page load.
In the component i added a Ref to the select and updated the selected value using a useEffect with a watch on my prop:
let mySelect = useRef<HTMLIonSelectElement|null>(null)
React.useEffect(()=>{
mySelect.current!.value = props.theJob.jobStatus?.toString();
},[props.theJob.jobStatus])
In the IonSelect I set the ref and also set the value of the select to the refs current value:
<IonSelect
id="jobStatus"
ref={mySelect}
value={mySelect.current?.value} ....
Finally, in the parent component where the data is being fetched. I ensure I await the fetch of the options of the select prior to awaiting the data for the preselected value fetch. Its now working as expected. The UI seems responsive and there doesn't seem to be a noticeable overhead. Hopefully it will help someone if they stumble upon this.

I want keep the text in the filer section after a Material-Table rendering

Im filtering using remote mode in the Material-Table component, but after each filtered, and Material-Table rendered, it delete the text or selection from the filter section.
So I would like to understand if there is a way in the table to keep this values, because it is necessary that the user have reference of what he is seeing in the table.
Im using the last version, 1.32
This is the component https://github.com/mbrn/material-table
Best Regards and thanks in advance for your time in my case
Move your columns object to a state.
Make a state var,
const [materialColumn] = useState([{title: "Name",field: "name"}]);
Then on your material table
<MaterialTable
columns={materialColumnObj}
/>
This will solve the problem. The filter text will stay. Cheers!

Integrate mui-datatable with admin-on-rest

How to integrate mui-datatable with admin-on-rest?
Need the following options in the list view :
move around ordering of columns
show/hide columns
change the number of rows for display
print preview of table
Mui-datatable has these features. According to admin-on-rest documentation, we can use custom Datagrid. Can anyone explain how to do it?
Say you are making a custom-datagrid component 'MyIterator'. This component has to just make use two props that will 'auto-magically' be available to the child of 'List' component. One prop is ids and another is data.
The ids prop is an array of id of currently displayable data-items. And the data is an object containing the data for all the items displayable.
Something like this should do the part of making a custom-datagrid -
const MyIterator = ({ids, data}) => ids.map(id=><div key={id}><span>Label</span><span>{data[id].label}</span></div>)
Above example presumed the data-item object to have a property of 'label'.
And this is how a custom-datagrid can be made.

How to return data on selection of multiple rows in React material ui table?

/*
Details :
I am looking for a way to implement table in such a way that
I can add or remove the data on click or selection of row.
Also can we use native js events in the material - ui
Also, if any library is there, please share as soon as possible.
*/
Map over the table row data and add a prop for this.handleEdit.bind(this, data.id) and this.handleRemove.bind(this, data.id). Then in those functions, use the id to make an api call to update or delete the row.

How to use Select in ReactJS, and creating its options with an Array

I'm new to ReactJS. Well I only want to solve this problem, nothing else I want from React. In my already build app, SelectField (of Material-UI) is used, which do not show the selected value. Other than this everything works fine. Here is the Markup:
<SelectField ref="device" selectedIndex={this.state.deviceIndex} displayMember="device_model" valueMember="device_id" menuItems={this.state.devices} onChange={this.onSelectDevice} style={{float:"left", marginTop:"5px", width:"300px"}} />
I want one of the two things:
1. Either solve my problem with the existing SelectField component, after which I will be able to get the selected item. OR
2. Share the method of working with simple HTML Select...
You must pass the menu items to display as children to the SelectField component. This is easy with an inline mapping expression.
Example:
<SelectField selectedIndex={this.state.deviceIndex}>
{this.state.devices.map(device =>
<MenuItem value={device.id} primaryText={device.name}/>
)}
</SelectField>

Resources