react-remount-component
v1.0.0
Published
<!-- START doctoc generated TOC please keep comment here to allow auto update --> <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
Downloads
3
Readme
react-remount-component
The Problem
You want a React component to reset state when certain props change. Without this library you can do this:
- Class components: implement
getDerivedStateFromProps
andcomponentDidUpdate
to track and respond to props changes - Function components: use a state hook with a cache of previous props to manually call the
set
function of related state hooks - Either: rely on consumers to pass a
key
. This can't be enforced and removes control over internal state from the library.
This Solution
react-remount-component
is a higher-order component that takes a comparison function for new props and previous props. Returning true
from the comparison remounts the component.
Currently, the HOC generates a random key for the wrapped component when a reset is requested. This is an implementation detail that may change in the future.
Usage
Class Component
See usage.test.js
class UserCard extends React.Component {
state = {
expanded: false,
};
render() {
const { user } = this.props;
return (
<div className="user-card">
<Name name={user.name} />
<button onClick={() => this.setState({ expanded: true })}>
Details
</button>
{this.state.expanded && (
<React.Fragment>
<Date date={user.birthdate} />
<Avatar user={user} />
</React.Fragment>
)}
</div>
);
}
}
export default withRemount(UserCard, (props, prevProps) => {
const prevUserId = prevProps.user && prevProps.user.id;
const nextUserId = props.user && props.user.id;
if (nextUserId !== prevUserId) {
return true; // remount!
}
return false; // don't remount otherwise
});
Function Component
function UserCard(props) {
const { user } = props;
const [isExpanded, setExpanded] = React.useState(false);
return (
<div className="user-card">
<div>Name: {user.name}</div>
<div>
<button onClick={() => setExpanded({ expanded: true })}>
See Details
</button>
</div>
{isExpanded && (
<React.Fragment>
<div>Birthday: {user.birthDate}</div>
<div>Favorite Color: {user.favoriteColor}</div>
</React.Fragment>
)}
</div>
);
}
export default withRemount(UserCard, (props, prevProps) => {
const prevUserId = prevProps.user && prevProps.user.id;
const nextUserId = props.user && props.user.id;
if (nextUserId !== prevUserId) {
return true; // remount!
}
return false; // don't remount otherwise
});
React RFC
https://github.com/reactjs/rfcs/pull/62