【问题标题】:React how to call componentDidMount every time when switching between ListItemReact如何在ListItem之间切换时每次调用componentDidMount
【发布时间】:2020-05-10 07:57:46
【问题描述】:

在初始化加载各种图表的小部件组件时,它可以正常工作,但是当切换到另一个 ListItem 时,切换到另一个项目时不会加载 componentDidMount。我需要加载它,因为它为它获取所需的数据。但问题是当我在 ListItem 之间切换时没有初始化 componentDidMount

DashboardSidebar.jsx

class DashboardSidebar extends Component {
  constructor(props) {
    super(props);
    this.state = {
      tabLocation: this.props.tabLocation
    };
    this.onChange = this.onChange.bind(this);
  }
  onChange(event) {
    this.setState({
      tabLocation: event.target.value
    });
  }
  render() {
    const { classes } = this.props;
    const { path } = this.props.match;
    const { reports = [], sites = [] } = this.props;

    let fromFilterString = "-"
    let toFilterString = "-"

    return (
      <Drawer
        className={classes.drawer}
        variant="permanent"
        classes={{
          paper: classes.drawerPaper,
        }}>
        <div>
          <List>
            {reports.map((report) => (
              <ListItem 
              onClick={this.onChange} button key={report.id}>
                <ListItemIcon>
                  <DashboardIcon />
                </ListItemIcon>
                <ListItemText
                  disableTypography
                  primary={
                    <Typography type="body2">
                      <Link to={`${path}/${report.slug}`} style={{ color: "#000" }}>
                        {report.name}
                      </Link>
                    </Typography>
                  }
                />
              </ListItem>
            ))}
          </List>
        </div>
        <Divider light />
      </Drawer>
    )
  }
}

这个组件似乎运行正确,但是当点击其他 ListItem 运行 componentDidUpdate 时,它不会获取图表所需的数据。我还发现,当我将 MainDashboard 组件 key={i} 更改为 key={l.id} 时,开始点击 componentDidMount,但随后小部件没有加载,但从控制台我可以看到它点击 componentDidMount 并获取我console.log().

MainDashboard.jsx

class MainDashboard extends Component {
  componentDidUpdate(prevProps) {
    if (this.props.match.params.report === prevProps.match.params.report) {
      return true;
    }
    let widgets = {};
    let data = {};
    let layout = {};
    fetch(...)
      .then(response => response.json())
      .then(data => {
        ...
        this.setState({dashboard: data, isLoading: false, layouts: layout });
      })
  }

  componentDidMount() {
    this.setState({ mounted: true, isLoading: true });
    let widgets = {};
    let data = {};
    let layout = {};

    fetch(...
    })
      .then(response => response.json())
      .then(data => {
          ...
        this.setState({dashboard: data, isLoading: false, layouts: layout });
      })
  }

  sortWidgets(widgets) {
    ...
    return widgets;
  }

  generateDOM() {
    return _.map(this.state.dashboard.widgets, function(l, i) {
        ....
      return (
        <div key={i}>
            <ChartWidget
              visualization={l.visualization}
              name={l.visualization.name}
        </div>
      );
    }.bind(this));
  }
  render() {

    return (
      ...
    );
  }
}

【问题讨论】:

  • 在 HTML 或 React synthetic events 中你不会得到 evt.value,而是 evt.target.value,所以下面的:_onSwitchTab = (value) =&gt; ... 无效,应该是 _onSwitchTab = (evt) =&gt; { const value = evt.target.value。如果它不起作用,你应该告诉我们函数setCurrentDashboard做了什么
  • @Tyblitz 我将 _onSwitchTabvalue 更改为 evt 并设置为 value ,但它不起作用。是的,我会用 setCurrentDashboard 更新我的问题
  • @PrakashKarena 不,_onSwitchTab 不是问题
  • 当点击 DashboardSidebar.jsx 中的任何链接 ${path}/${report.slug}} /> 时,您想在 BaseDashboard.jsx 中调用您的 fetch 请求。我说得对吗???

标签: javascript reactjs routing jsx listitem


【解决方案1】:

您有三个选择:
1-使用另一个生命周期,例如componentDidUpdate,如果道具或状态有特殊变化,则获取新数据
2- 使用一个新的Key,如果你在一个组件上使用一个新的key,它会触发一个componentDidMount,因为组件被再次渲染为一个新的实体
3- 使用react.ref
我认为您应该阅读所有三个选项,然后选择一个最适合您的选项。

【讨论】:

    【解决方案2】:

    所以componentDidMount 实际上被击中但在数据更新方面没有发生任何事情?在这种情况下,您的组件首先加载/挂载,并且无论发生什么都不会触发重新渲染,我会考虑使用另一种生命周期方法来确保您的数据得到更新。

    我不确定您是否在使用旧系统,但如果可以选择升级到功能组件,我建议您使用生命周期方法 useEffect,因为它取代了许多生命周期方法,例如 componentDidMount、@987654324 @ 和不安全的 componentWillUnmount 会让你的生活变得更轻松、更高效。

    【讨论】:

    • 重新渲染不会重新执行componentDidMount
    【解决方案3】:

    componentDidMount 仅在安装组件时执行。 DashboardSidebar 中的状态更新不会导致 BaseDashboard 重新挂载,因此 componentDidMount 不会为 BaseDashboard 重新执行。

    您是否尝试过在 onChange 事件处理程序中获取数据(用于切换到另一个 ListItem)?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-09-30
      • 1970-01-01
      • 2018-09-22
      • 2018-01-02
      • 2023-04-03
      • 1970-01-01
      • 2019-12-07
      • 2019-08-27
      相关资源
      最近更新 更多