This is an example array of objects:
[ { "id": 1, "class": "Assault Infantry", "missions": 5, "shots": 28, "hits": 21, "kills": 22, "dead": true, }, { "id": 2, "class": "Field Medic", "missions": 5, "shots": 22, "hits": 17, "kills": 15, "dead": false, }, { "id": 3, "class": "Field Medic", "missions": 3, "shots": 15, "hits": 11, "kills": 8, "dead": true, }, { "id": 4, "class": "Skirmisher", "missions": 7, "shots": 38, "hits": 27, "kills": 25, "dead": false, }, { "id": 5, "class": "Phalanx", "missions": 2, "shots": 5, "hits": 3, "kills": 5, "dead": true, }, { "id": 6, "missions": 6, "shots": 50, "hits": 41, "kills": 31, "dead": false, }, { "id": 7, "class": "Rookie", "missions": 1, "shots": 2, "hits": 1, "kills": 1, "dead": true, },
I am trying to build a component, that parents several other components that receive this array from a parent, then filters the array and returns it to the parent. However, I want all of the child components use the same filtered array and then get the changed array.
This is the parent component:
const Navigation = ({soldiers, sortList}) => {
const [fullyFiltered, setFullyFiltered] = useState([]);
const [preFiltered, setPreFiltered] = useState(soldiers);
const onSort = (data) => {
setFullyFiltered(preFiltered);
}
const onDeadCheck = (data) => {
setPreFiltered(data);
}
useEffect(() => {
sortList(fullyFiltered);
},[onDeadCheck, onSort])
return (
<div>
<DeadSelector deadFiltered={onDeadCheck} soldiers={soldiers} />
<NavigationSort forSort={onSort} soldiers={soldiers}/>
</div>
)
};
Then the two child components that filter array by different values.
This one filters the array by chosen value :
const NavigationSort = ({soldiers, forSort}) => {
const [sortType, setSortType] = useState('kills');
console.log(soldiers);
useEffect(() => {
const sortArray = type => {
const types = {
mvps: 'mvps',
kills: 'kills',
shots: 'shots',
missions: 'missions',
};
const sortProperty = types[type];
if(sortType === "accuracy") {
const sorted = soldiers.sort((a, b) => (b.hits / b.shots * 100) - (a.hits / a.shots * 100));
forSort(sorted);
} else {
const sorted = soldiers.sort((a, b) => b[sortProperty] - a[sortProperty]);
forSort(sorted);
}
};
sortArray(sortType);
}, [sortType]);
return (
<>
<p>Sort by</p>
<ul onClick={(e) => setSortType(e.target.getAttribute("data-id"))}>
<li data-id="kills" value="kills">
Kills
</li>
<li data-id="missions" value="missions">
Missions
</li>
<li data-id="shots" value="shots">
Shots
</li>
<li data-id="accuracy" value="accuracy">
Accuracy
</li>
</ul>
</>
)
};
This one removes the instances that have value of “dead” set as true:
const DeadSelector = ({soldiers, deadFiltered}) => {
const [isChecked, setIsChecked] = useState(false);
useEffect(() => {
let sorted = [];
(isChecked ? sorted = soldiers.filter((user) => user.dead !== true) : sorted = soldiers);
deadFiltered(sorted);
},[isChecked])
const handleOnChange = () => {
setIsChecked(!isChecked);
};
return (
<div className={classes.dead__checker}>
<input onChange={handleOnChange} type="checkbox" id="isDead" name="isDead" checked={isChecked} />
<label htmlFor="isDead">Hide Dead</label>
</div>
)
}
My problem is, I can’t figure out a way so that these two components “talk” to each other and do their function once the array is changed through the other child component. I was trying to have a state of preFiltered, where the shared array would be stored, instead what happens is that they change filter the array and return it, disregarding whether it was changed in the other component or not. Any help or at least pushing me to the right path would be much appreciated.