Reputation: 3117
I did not use reducer for this case to update state change on component. I send prop to child Component and I want it will be updated every time state changed on parent Component.
In the mother Component, I set state currentPage by default is 1;
const [pager, setPager] = useState({
currentPage: 1
});
const propToSend = pager.currentPage;
//and make trigger change:
const onClick = (e) => {
setPager({...pager, currentPage:5});
}
....return...
<Pagination pageProp={propToSend} />
in Pagination Component I got state and set it into new State:
const Pagination = (props) => {
const currentPage = props.pageProp
const [pager, setPager] = useState({
currentPage
});
const changeActivePage(num)=> {
setPager({..pager, currentPage:num});
}
.....
const paginomal = ListPagers.map(num => (
<li key="num" onClick={changeActivePage(num)}>{num}</li>
));
return(
<Fragment>
{paginomal}
</Fragment>
)
}
If you can see if I make change pager on mother Compoment with function
//and make trigger change:
const onClick = (e) => {
setPager({...pager, currentPage:5});
}
Then nothing happen on pager.
Can you tell me how to trigger to change from mother Component because state is changed with click event on Child?
Upvotes: 0
Views: 48
Reputation: 202721
You need to update your pagination state when the currentPage from props updates. Using an effect hook can accomplish this. The useEffect
hook triggers once for the first mount of the component, then again each time a value in its dependency array (the second argument) is changed. In this case, when the currentPage
value is changed from, say, 1 to 2.
const Pagination = (props) => {
const currentPage = props.pageProp;
const [pager, setPager] = useState({
currentPage
});
useEffect(() => setPager(currentPage), [currentPage]);
const changeActivePage(num)=> {
setPager({..pager, currentPage:num});
}
.....
const paginomal = ListPagers.map(num => (
<li key="num" onClick={changeActivePage(num)}>{num}</li>
));
return(
<Fragment>
{paginomal}
</Fragment>
)
}
But now you've two sources of truth!! And it can be difficult to keep them in sync, hence the above issue you had. It may be better to instead pass the setPager
function from the "mother" to the child as a callback. It then updates the state stored in the parent component, the single source of truth.
const Pagination = ({ pageProp, onPageChange }) => {
const currentPage = pageProp;
const changeActivePage(num)=> {
onPageChange({ currentPage: num });
}
.....
const paginomal = ListPagers.map(num => (
<li key="num" onClick={changeActivePage(num)}>{num}</li>
));
return(
<Fragment>
{paginomal}
</Fragment>
)
}
Then from Mother
const [pager, setPager] = useState({
currentPage: 1
});
const propToSend = pager.currentPage;
//and make trigger change:
const onClick = (e) => {
setPager({...pager, currentPage:5});
}
....return...
<Pagination pageProp={propToSend} onPageChange={setPager} />
Upvotes: 1
Reputation: 414
If you do not want to keep a separate state in your child component then you should pass you onClick
method as props to your child component and then use it something like below
const paginomal = ListPagers.map(num => (
<li key="num" onClick={() => onClick(num)}>{num}</li>
));
And in your parent component you can write something like
//and make trigger change:
const onClick = (num) => {
setPager({...pager, currentPage:num});
}
....return...
<Pagination pageProp={propToSend} onClick={onClick}/>
Upvotes: 1