调用具有不同参数的 Route 时不调用 componentDidMount

IT技术 reactjs redux
2021-05-06 03:49:33

我在我的 UsersListContainer 的回调中渲染“详细信息”组件,如下所示:

class UsersListContainer extends Component {
  goToUserById(id) {
    if (!id) { return false; }
    this.props.history.push(`/users/${id}`);
  }

  render() {
    return (
      <UserList
      goToUser={(id) => this.goToUserById(id)}/>
    );
  }
}

我的“详细信息”容器:

class UserDetailsContainer extends Component {
  componentDidMount() {
    this.props.getUserDetails(this.props.match.params.id);
  }

  render() {
    return (
      <UserDetails user={this.props.selectedUser}/>
    );
  }
}

const mapDispatchToProps = dispatch => {
  return {
    getUserDetails: id => dispatch(getUser(id))
  };
};

const mapStateToProps = (state) => ({
  selectedUser: state.user.selectedUser
});

在我的展示性“用户”组件中,我显示了一组来自 redux 存储的数据,如下所示:

class UserDetails extends Component {
  constructor(props) {
    super(props);
    this.state = {
      name: this.props.user.name,
      address: this.props.user.name,
      workingHours: this.props.user.workingHours,
      phone: this.props.user.phone
    };
  }

我没有直接显示组件props,而是使用状态,因为它们是要编辑的。这是可行的,但问题是所有这些props都不会与组件加载同时更新,这意味着当我第一次选择用户时,它会显示正确的信息,然后我切换回“/users”以选择另一个,以及他的props保持与前一个用户的props相同。我试过 componentWillUnmount 来清除数据,但没有用

2个回答

通过在我的展示组件中使用 lodash lib 解决了这个问题,我比较了对象是否相等

 constructor(props) {
    super(props);
    this.state = {
      name: "",
      address: ""
    };
  }

  componentWillReceiveProps(nextProps) {
    _.isEqual(this.props.user, nextProps.user) ? (
      this.setState({
        name: this.props.user.name,
        address: this.props.user.address
      })
    ) : (
      this.setState({
        name: nextProps.user.name,
        address: nextProps.user.address,
      })
    )
  }

当您实现类似 Route 时/users/:id,如果将 id 更改为其他内容,则不会重新安装整个组件,因此componentDidMount不会调用Route ,而只会更改props,因此您还需要实现componentWillReceiveProps功能

componentDidMount() {
    this.props.getUserDetails(this.props.match.params.id);
}

componentWillReceiveProps(nextProps) {
    if(this.props.match.params.id !== nextProps.match.params.id) {
        this.props.getUserDetails(nextProps.match.params.id);
    }
}