1.0.0 • Published 7 years ago
react-remount-component v1.0.0
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 
getDerivedStateFromPropsandcomponentDidUpdateto track and respond to props changes - Function components: use a state hook with a cache of previous props to manually call the 
setfunction 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
License
Contributing
1.0.0
7 years ago