I'm super new to React JS and developing small employee data view and filtering app. Below is my working code.
EmployeeList.js
function EmployeeList(props) {
const [mainData, setMainData] = useState(props.data);
const [selectedDept, setSelectedDept] = useState(null);
const [selectedLocation, setSelectedLocation] = useState(null);
var departmentCodes = [...new Set(props.data.map(item => item.department))];
departmentCodes.push("-SELECT-");
departmentCodes.sort();
var locationCodes = [...new Set(props.data.map(item => item.factoryLocation))];
locationCodes.push("-SELECT-");
locationCodes.sort();
const handleComboDepartment = (event) => {
setSelectedDept(event);
filterAgain("Department", event);
};
const handleComboLocation = (event) => {
setSelectedLocation(event);
filterAgain("FactoryLocation", event);
};
function search(user) {
return Object.keys(this).every((key) => user[key] === this[key]);
}
function filterAgain(type, data) {
var query = {
department: type == "Department" ? data : selectedDept,
factoryLocation: type == "FactoryLocation" ? data : selectedLocation
}
let filteredQry = Object.fromEntries(Object.entries(query).filter(([_, v]) => v != null && v != "-SELECT-"));
var filteredData = props.data.filter(search, filteredQry);
setMainData(filteredData);
}
return (
<div>
<div>
<table className={classes.table}>
<thead>
<tr>
<th>Id</th>
<th>Employee Name</th>
<th>Department
<Combobox
data={departmentCodes}
defaultValue={departmentCodes[0]}
onChange={handleComboDepartment}
/>
</th>
<th>Factory Location
<Combobox
data={locationCodes}
defaultValue={locationCodes[0]}
onChange={handleComboLocation}
/>
</th>
</tr>
</thead>
<tbody>{mainData.map((ele =>
<tr key={nanoid()}>
<td>{ele.id}</td>
<td>{ele.employeeName}</td>
<td>{ele.department}</td>
<td>{ele.factoryLocation}</td>
</tr>
))}</tbody>
</table>
</div>
</div>
);
}
export default EmployeeList;
Above code is working totally fine and gives below output
when it change the combo box, then it is displaying data according to the filteration. That works totally fine.
As you can see, the combo box is repetitive (there are 2 combo boxes) and I need it to be defined a combo box as separate component, since React JS concept is to reuse components. (In my above code I repeat it twise) Then I define a new component as CommonCombo.js and modify the EmployeeList.js file.
Here is new EmployeeList file and CommonCombo file
EmployeeList.js
function EmployeeList(props) {
const [mainData, setMainData] = useState(props.data);
var departmentCodes = [...new Set(props.data.map(item => item.department))];
departmentCodes.push("-SELECT-");
departmentCodes.sort();
var locationCodes = [...new Set(props.data.map(item => item.factoryLocation))];
locationCodes.push("-SELECT-");
locationCodes.sort();
return (
<div>
<div>
<table className={classes.table}>
<thead>
<tr>
<th>Id</th>
<th>Employee Name</th>
<th>Department
<CommonCombo
data={departmentCodes} />
</th>
<th>Factory Location
<CommonCombo
data={locationCodes} />
</th>
</tr>
</thead>
<tbody>{mainData.map((ele =>
<tr key={nanoid()}>
<td>{ele.id}</td>
<td>{ele.employeeName}</td>
<td>{ele.department}</td>
<td>{ele.factoryLocation}</td>
</tr>
))}</tbody>
</table>
</div>
</div>
);
}
export default EmployeeList;
CommonCombo.js
function CommonCombo(props) {
const handleCombo = (event) => {
//I need to pass event to EmployeeList.js for filtering data
};
return (
<div>
<div className={classes.divWidth}>
<Combobox
data={props.data}
defaultValue={props.data[0]}
onChange={handleCombo}
/>
</div>
</div>
);
}
export default CommonCombo;
In here (CommonCombo) I need to pass the selected value to EmployeeList.js file for filtering data. I stuck with it. Can any one show me a direction for doing it?
Additional Data:
Used combo box is react-widgets/Combobox.
Employee Sample Data set :
const EmpData = [ { "id": 5486, "employeeName": "John", "department": "HR", "factoryLocation": "Denmark" }, { "id": 5487, "employeeName": "Almeda", "department": "Admin", "factoryLocation": "Austria" }, { "id": 5488, "employeeName": "Kent", "department": "Production", "factoryLocation": "Denmark" }, { "id": 5489, "employeeName": "Peter", "department": "Production", "factoryLocation": "Austria" }, { "id": 5490, "employeeName": "Swargen", "department": "HR", "factoryLocation": "Austria" }, { "id": 5491, "employeeName": "Tim", "department": "Admin", "factoryLocation": "Austria" }, { "id": 5492, "employeeName": "Pat", "department": "HR", "factoryLocation": "Austria" }, { "id": 5492, "employeeName": "Nick", "department": "Marketing ", "factoryLocation": "Denmark" }, { "id": 5493, "employeeName": "Letrim", "department": "Production", "factoryLocation": "Austria" }, { "id": 5494, "employeeName": "Bingo", "department": "HR", "factoryLocation": "Denmark" }, { "id": 5495, "employeeName": "Sarwen", "department": "Production", "factoryLocation": "Denmark" }, ];
CodePudding user response:
Just pass onChange prop to your CommonCombo component
<th>
Department
<CommonCombo
data={departmentCodes}
onChange={handleComboDepartment}
/>
</th>
<th>
Factory Location
<CommonCombo
data={locationCodes}
onChange={handleComboLocation}
/>
</th>
function CommonCombo(props) {
return (
<div>
<div className={classes.divWidth}>
<Combobox
data={props.data}
defaultValue={props.data[0]}
onChange={props.onChange}
/>
</div>
</div>
);
}
CodePudding user response:
You can define a function in your EmployeeList
component that receives the event and then filters the data. This function has to be passed via props
to your CommonCombo
component. Example:
In your EmployeeList
component:
function EmployeeList(props) {
const [mainData, setMainData] = useState(props.data);
var departmentCodes = [...new Set(props.data.map(item => item.department))];
departmentCodes.push("-SELECT-");
departmentCodes.sort();
var locationCodes = [...new Set(props.data.map(item => item.factoryLocation))];
locationCodes.push("-SELECT-");
locationCodes.sort();
const handleComboData = (data) => {
// Handle your data coming from CommonCombo component
}
return (
<div>
<div>
<table className={classes.table}>
<thead>
<tr>
<th>Id</th>
<th>Employee Name</th>
<th>Department
<CommonCombo
data={departmentCodes}
handleComboData={handleComboData}
/>
</th>
<th>Factory Location
<CommonCombo
data={locationCodes}
handleComboData={handleComboData}
/>
</th>
</tr>
</thead>
<tbody>{mainData.map((ele =>
<tr key={nanoid()}>
<td>{ele.id}</td>
<td>{ele.employeeName}</td>
<td>{ele.department}</td>
<td>{ele.factoryLocation}</td>
</tr>
))}</tbody>
</table>
</div>
</div>
);
}
export default EmployeeList;
In your CommonCombo
component:
function CommonCombo({ data, handleComboData }) {
const handleCombo = (event) => {
//I need to pass event to EmployeeList.js for filtering data
handleComboData(event);
};
return (
<div>
<div className={classes.divWidth}>
<Combobox
data={props.data}
defaultValue={props.data[0]}
onChange={handleCombo}
/>
</div>
</div>
);
}
export default CommonCombo;
Note: the other solution would be to move your change handle functions to the top level component (EmployeeList
) and do prop drilling (passing these functions to your CommonCombo
and then passing them to Combobox
from that point).