I have created a custom table component I forked from ant design. I reuse it in all my components, It takes an array of all columns and renders it. I pass columns as a prop called initialColumns.
My issue is whenever the user changes the language, the table contents is re rendering but not the columns which I passed, they don't get translated, How would I force a rerender when the language is changed.
custom table component
const TableComponent = (props) => {
const { initialColumns, dataSource, handleClick } = props
return ( <Table
columns={colmenu.visibleColumns}
dataSource={dataSource}
size="small"
pagination={{
pageSizeOptions: ['10', '20', '50'],
showSizeChanger: true,
}}
/>)
}
Parent component, here I call my TableComponent as pass it columns
It looks something like this:
const columns = [
{
title: t.status,
dataIndex: 'status',
key: 'status',
sorter: (a, b) => a.status.localeCompare(b.status),
...GetColumnSearchProps(['status']),
className: 'text-center',
checked: true,
},
.
.
.
.
here is how I get the translated files
const { messages: t } = useIntl()
and this is the render method:
<TableComponent
initialColumns={columns}
dataSource={data}
handleClick={addModal}
title="AABC"
/>
So how would I update the initialColumns prop when the language is changed?
Related
Using antd 4.22.8 with react 18.2.0 (cra). Typescript code ahead
I'm using this code to fetch the data I need to show
const [pagination, setPagination] = useState<TablePaginationConfig>({
current: 1,
pageSize: 10
});
const [sort, setSort] = useState<SorterResult<FOO>>();
const [searchString, setSearchString] = useState<string>();
const [{ data, loading, error }, refetch] = useAxios<FOO[]>({
url: '/endpoint',
params: { skip: ((pagination.current ?? 0) - 1) * (pagination.pageSize ?? 0), take: pagination.pageSize, sortField: sort?.field, sortDirection: sort?.order, search: searchString }
});
const onTableChange: TableProps<FOO>['onChange'] = (pagination, _filters, sorter) => {
setPagination(pagination);
setSort(sorter as SorterResult<FOO>);
};
and this is how the data is shown
<Input.Search placeholder="Search" allowClear onChange={e => setSearchString(e.target.value)} />
<Table
rowKey={record => record.id}
loading={loading}
columns={[
{
title: 'ICCID',
dataIndex: 'id',
sorter: true
},
{
title: 'Name',
dataIndex: 'name',
sorter: true
}
]}
dataSource={data?.data}
pagination={{ position: ['topRight', 'bottomRight'], total: data?.count ?? 0, ...pagination }}
onChange={onTableChange}
/>
The problem arises with the pagination in this component. Imagine these 2 use case:
You never changed page: I can use the search field to perform some search. Pagination changes correctly reflecting the data that came from the endpoint (different page count, etc...).
I've changed the page: on the first load the endpoint returns quite lot of record and you move to, say, page 4 clicking on the relative button on the paginator component. Then perform a search: data returns correctly but pagination does not reflect changes anymore. Page count is still pre-search, and so is the selected page, but not showing page 4 of the freshly searched dataset, but page 1.
What I'd expect is the pagination component is reset itself after dataset changes, as it does when changing pages or sort
Im using class component in my application.
I want to set the value to the table column button. and i fetch the value from backend
it was an array response. Array values auto mapped by my table column key.
Ex: This was my table column and it was auto mapped by fetch response name. fetch response name
is "description".
{
title: 'Description',
dataIndex: 'description',
key: 'description',
sorter: true
},
But problem is how auto mapped to the response name to switch button I try but I can't.
My Switch column:-
{
title: 'Action',
dataIndex: 'enabled',
key: 'enabled',
render: (text: any, record: any) => (
<div>
<Tooltip title="Enable / Disable" color={'#d31145'}>
<Switch autoFocus checkedChildren="Enable" unCheckedChildren="Disable" className={'customswitch'} onChange={checked => this.changeSwitch(checked,record.proId)}/>
</Tooltip>
</div>
),
}
I need to know how to set the fetch value to switch button in react class component.
I fetch All data from using this code.
fetch = (params: any = {}) => {
let providerConfigureDto: ProviderConfigureDto = {...this.state.providerConfigureDto};
this.setState({isLoading: true});
providerConfigureService.getAllProviders(providerConfigureDto).then(res => {
console.log(res.data.content)
const pagination: any = {...this.state.pagination};
pagination.total = res.data.total;
this.setState({
isLoading: false,
total: res.data.totalElements,
providerConfigures: res.data.content,
providerConfigureDto: providerConfigureDto,
pagination
});
})
providerConfigureDto.page = 0
};
ProviderConfigureDto has only sorter option and pagble option only.
I fetch from array from back end and i create a array in state. then i set the array to table datasouce
Like this :-
providerConfigures:Array<any>,
That's all please help me for that.
I'm trying to pass props from an onclick event to a function when then renders a component based on those prop values. The problem is that i am not able to pass on the props to the functional component. But it returns undefined
here is the parent component that passes the props using the map function
<DropdownButton id="dropdown-basic-button" title="Dropdown Menu">
{post && (postVideoInfo = post.video_info, postVideoInfo.map((postVideoSource) => (
<Dropdown.Item key={postVideoSource.id} onClick={RenderVideoPlayer} props={postVideoSource}>{postVideoSource.audio_language}</Dropdown.Item>
)))}
</DropdownButton>
here is the functional component that renders a new component on click
const RenderVideoPlayer = (props) => {
let videoSrc = {
type: 'video',
sources: [
{
src: `${props.video_url}`,
type: 'video/mp4',
}
],
poster: '/path/to/poster.jpg',
tracks: [
{
kind: 'captions',
label: `${props.caption_language}`,
srclang: 'en',
src: `${props.video_url}`,
default: true,
}
],
}
return (
<Plyr
options={options}
source={videoSrc}
/>
)
}
That data is retrieved from an api and stored in setState
It clearly seems like RenderVideoPlayer is not being passed any info from the postVideoSource in the map.
Rewriting the onClick as this could work, as you will be passing the props (I am guessing postVideSource has the 2 pieces of info that RenderVideoPlayer is expecting):
onClick={() => {
return <RenderVideoPlayer
video_url={postVideoSource.videoUrl}
caption_language={props.captionLanguate}
/>
}
I am also assuming this RenderVideoPlayer is going to be rendered inside a modal or some overlay or some side div...
I am building a react functional component with an AgGridReact:
const DataGrid = (props) =>
{
const [gridRowData, setGridRowData] = useState([]);
const [columnDefinition, setColumnDefinition] = useState([]);
useEffect(async () =>
{
if(props.name && props.name !== "")
{
... get grid row data and column definition here according to props.name - working fine
}
},[props.name]);
let frameworkComponents = {
customLoadingOverlay: LoadingOverlayTemplate,
customNoRowsOverlay: UxDataGridCustomNoRows,
editButton: params => <ViewAndDeleteSetting {...params}
openAddConfigurationsWindow={openAddConfigurationsWindow}
onDeleteSetting={onDeleteSetting} />
};
.
.
.
const onDeleteSetting = async () =>
{
console.log("ON DELETE AND NAME IS: " + props.name ); //PRINTS AN EMPTY STRING
...
}
return (
<AgGridReact
columnDefs={columnDefinition}
rowData={gridRowData}
frameworkComponents={frameworkComponents}/>
);
As you can see in the comment in onDeleteSetting, the name is empty when this callback is invoked. The rendering of the cell itself is fine and ViewAndDeleteSetting is indeed rendered, just it seems like it is being rendered only once and not every time the name changes. How can I cause the inner ViewAndDeleteSetting component to be re rendered with the most recent frameworkComponents?
The problem was with how I tried passing props to ViewAndDeleteSetting. If you want to pass prop to a cell rendered component, you shouldn't be doing it in frameworkComponents, but rather you need to do it in the column definition like this:
useEffect(() =>
{
let columns = [{headerName: '', cellRenderer: 'editButton', width: 90, editable: false,
cellRendererParams: {
openAddConfigurationsWindow: openAddConfigurationsWindow,
onDeleteSetting: onDeleteSetting
}},
.. other columns
]
setColumnDefinition(columns);
},[props.name]);
The columns with the cellRendererParams do gets recreated in the useEffect when the name changes, and then the component can access this params regularly via its props
I have this React component
import React from "react";
import "./search.css";
// Table package
import MaterialTable from 'material-table';
function BasicSearch(props) {
return (
<div className="hovered-styled-row">
<MaterialTable
title="Students"
columns={[
{ title: 'Name', field: 'name' },
{ title: 'Surname', field: 'surname' }
]}
data={props.data}
options={{
search: true
}}
actions={[
{
icon: "add",
tooltip: 'Save User',
onClick: (event, rowData) => {
// console.log(rowData);
}
}
]}
/>
</div>
)
}
export default BasicSearch;
I am using Material Design for this component. I need to export a rowData variable which is inside
actions inside onClick.
Then the container which imports this function should be able to use this data inside a container itself. when the rowData changes the data inside a container should also change. i mean the rowData has to be
in the form of a useState function
The approach you are taking is wrong. The below are the ways to pass data from one component to another depending on your design structure.
Pass data as props and use events to communicate data changes back to parent.
If global data/or shared data use Context API.
Without full context of how the data is intend to be used and how the final jsx looks like, it's difficult to further update this answer.