const Create = () => {
console.log('rerender !!')
const [parcelType, setParcelType] = useState('paper')
console.log('parcelType =', parcelType)
return (
<Container onClick={() => setParcelType('plastic')}>
<BookingList />
<Card title="Business">
<p>Header</p>
</Card>
</Container>
)
}
export default Create
I want to change parcelType state to 'plastic' when click on Container in Create ponent. and I want to reset parcelType state to 'paper' when route is change ( Create ponent re-render ). But when ponent re-render state is not set to paper
For more details: CreateComponent is re-render when route is change in BookingList ponent
const BookingList = props => {
const { id } = props.match.params
const containerStyle = useTranslateSpring('-100px', '0')
const itemList = items.map((item, idx) => {
const itemStyle = useTranslateSpring('-100px', '0', '0', 200 + 200 * idx)
const url = `/booking/${item.id}/create`
return (
<ItemContainer
onClick={() => props.history.push(url)}
style={itemStyle}
key={item.id}
isactive={id === item.id}
>
{item.id}
</ItemContainer>
)
})
return <Container style={containerStyle}>{itemList}</Container>
}
export default withRouter(BookingList)
Create Component is render in route by routeTemplate
const Routes = () => (
<Router basename={process.env.REACT_APP_BASE_URL}>
<>
<RouteTemplate
exact
path="/booking/:id/create"
ponent={Booking.create}
title="Booking"
/>
</>
</Router>
)
and RouteTemplate is render Component wrapped by PageTemplate ponent
const RouteTemplate = props => {
const {
ponent: Component,
title,
query,
isAuthenticated,
isLanding,
...rest
} = props
return (
<Route
{...rest}
render={matchProps =>
isAuthenticated ? (
<PageTemplate title={title} isLanding={isLanding}>
<Component {...matchProps} query={query} />
</PageTemplate>
) : (
<Redirect
to={{
pathname: '/',
state: { from: props.location },
}}
/>
)
}
/>
)
}
const Create = () => {
console.log('rerender !!')
const [parcelType, setParcelType] = useState('paper')
console.log('parcelType =', parcelType)
return (
<Container onClick={() => setParcelType('plastic')}>
<BookingList />
<Card title="Business">
<p>Header</p>
</Card>
</Container>
)
}
export default Create
I want to change parcelType state to 'plastic' when click on Container in Create ponent. and I want to reset parcelType state to 'paper' when route is change ( Create ponent re-render ). But when ponent re-render state is not set to paper
For more details: CreateComponent is re-render when route is change in BookingList ponent
const BookingList = props => {
const { id } = props.match.params
const containerStyle = useTranslateSpring('-100px', '0')
const itemList = items.map((item, idx) => {
const itemStyle = useTranslateSpring('-100px', '0', '0', 200 + 200 * idx)
const url = `/booking/${item.id}/create`
return (
<ItemContainer
onClick={() => props.history.push(url)}
style={itemStyle}
key={item.id}
isactive={id === item.id}
>
{item.id}
</ItemContainer>
)
})
return <Container style={containerStyle}>{itemList}</Container>
}
export default withRouter(BookingList)
Create Component is render in route by routeTemplate
const Routes = () => (
<Router basename={process.env.REACT_APP_BASE_URL}>
<>
<RouteTemplate
exact
path="/booking/:id/create"
ponent={Booking.create}
title="Booking"
/>
</>
</Router>
)
and RouteTemplate is render Component wrapped by PageTemplate ponent
const RouteTemplate = props => {
const {
ponent: Component,
title,
query,
isAuthenticated,
isLanding,
...rest
} = props
return (
<Route
{...rest}
render={matchProps =>
isAuthenticated ? (
<PageTemplate title={title} isLanding={isLanding}>
<Component {...matchProps} query={query} />
</PageTemplate>
) : (
<Redirect
to={{
pathname: '/',
state: { from: props.location },
}}
/>
)
}
/>
)
}
Share
Improve this question
edited Mar 20, 2019 at 7:51
skyboyer
23.7k7 gold badges62 silver badges71 bronze badges
asked Mar 20, 2019 at 5:46
sarin udompanitsarin udompanit
731 gold badge1 silver badge5 bronze badges
5
- When and where do you render Create ponent – Shubham Khatri Commented Mar 20, 2019 at 5:57
- Thank you I already add more information in post. @ShubhamKhatri – sarin udompanit Commented Mar 20, 2019 at 6:20
-
okay so one more question when you change the route by clicking on ItemContainer, from say
booking/1/create
tobooking/2/create
the create ponent is re-rendered. and not what I want to know is that in createComponent's Container onClick you change the state to plastic or you want to change it when the container is re-rendered with different id? – Shubham Khatri Commented Mar 20, 2019 at 6:27 - I want to change it to 'plastic' when click on Container in Create ponent. and I want to reset parcelType state to 'paper' when route is change ( Create ponent re-render ) – sarin udompanit Commented Mar 20, 2019 at 6:37
- so in other words you want ponent(its state particularly) be reset once route is changed, right? – skyboyer Commented Mar 20, 2019 at 6:49
1 Answer
Reset to default 15So I assume you want to reset ponent's state once route is changed.
This should happen wherever you use functional ponent + hooks or class-based ponent with explicit this.state
. It's how React works under the hood.
- You already have
<Create>
rendered at the page - Once route is changed
<Route>
tries to render<Create>
element - React sees there is already existing
<Create>
element and tries to update that instead of re-creating(typically update is much more efficient than re-creating). That's why state is not reset - since it should not reset for updates.
There are different way to handle that.
If such a case happen outside react-router's <Route>
I'd suggest use key
prop to reset state. But for <Route>
it would mean replacing more clear/straightforward <Route path="..." ponent={Create} />
with more verboose <Route path="..." render={({match}) => <Create match={match} key={match.params.id} />}
So instead let's apply useEffect
hook to reset state once props.match.params.id
is changed:
const Create = ({ match: {params: {id} } }) => {
useEffect(() => {
setParcelType('paper');
}, [id]);
That should be equal to class-based
state = {
typeOfWhatEver: 'paper'
};
ponentDidUpdate(prevProps) {
if(prevProps.match.params.id !== this.props.match.params.id) {
this.setState({
typeOfWhatEver: 'paper'
});
}
}