Reputation: 1522
In my react application, I have a Parent and Child component. In my parent component, i am including filters from Child component. Whatever values i select from filter, I am passing that to my api request param which is called under handleFilterChange method in my ParentComponent.But, i am noticing that if i select one filter from ChildComponent, it gets passed properly but on selecting two filters, it's always the latest selected filter value that gets passed. So, i think, i somehow need to save my previous state in handleFilterChange method but not sure how to achieve it. Here is my code snippet.
ParentComponent.js-
const ParentComponent = props => {
const [filterObj, setFilterObj] = useState({});
const handleFilterChange = filters => {
console.log(filters); // Show only latest selected filter
setFilterObj(filterObj);
//API call which will pass filters in request params
};
return (
<ChildComponent onChange={handleFilterChange} />
);
}
ChildComponent.js
const ChildComponent = props => {
const handleChange = value => {
console.log(values);// Shows all of the selected filters
onChange({
...Object.keys(values).reduce((val, key) => (isEmpty(value[key]) ? val : { [key]: value[key] }), {}),
});
};
return (
<Filter onFilterChange={handleChange} />
);
}
For Example, i have Filter A and Filter B. First time, when i select Filter A, i see parameter values has Filter A and same gets passed to my ParentComponent. But, when i select Filter B after having Filter A selected, it only passes Filter B(latest selected value) to my ParentComponent in handleFilterChange method. So, the filter parameter in handleFilterChange method will only have one object i.e Filter B. I am expecting it to have Filter A and Filter B. When selecting filters individually, my code works fine but only when i try to select both filters, it does not work. Any suggestion here would really help. Please note, the parameters, filters and values are objects.
Upvotes: 1
Views: 1096
Reputation: 2486
In ReactJs component allowance re-render the component when the component state are changed. So, when you change the filter from parent component you just update the state previous state ReactJs child component automatically re-render called.
Example this link here codesendbox.io or above this code:
import React, {useState} from "react";
import "./styles.css";
import Children from "./Children";
export default function App() {
const [filter, setFilter] = useState('A');
const handleChange = e => setFilter(e.target.value);
return (
<>
Filter:{" "}
<select onChange={(e)=>handleChange(e)}>
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
</select>
<Children filter={filter} />
</>
);
}
import React from "react";
const Children = props => {
return <h1>Children filder is : {props.filter}</h1>;
};
export default Children;
Finally, the output is:
Note: This answer is only for clear concept parent and chield in ReactJS
==== Thanks ====
Upvotes: 0
Reputation: 11
You can use useState() hook for updating the current state based on the previous state.
const [state, setState] = React.useState(default)
It take in the default value for your state.
React.useState() returns an array where the first value is the variable to store value for the state and second is the function which helps to update the value.
You can simply call the function passing the new value to it to update the state value.
Upvotes: 0
Reputation: 281626
In your child's handleChange
function you have't passed on the entire set of filters to parent onChange
.
Inside reduce you are overwriting the filters object always instead you need to merge the values
Updated code
const handleChange = value => {
console.log(values);// Shows all of the selected filters
onChange({
...Object.keys(values).reduce((val, key) => (isEmpty(value[key]) ? val : { ...val, [key]: value[key] }), {}),
});
};
Upvotes: 1