繁体   English   中英

Reactjs 子组件在设置时进入无限循环 state 父组件在 props 中提供的数组

[英]Reactjs child component goes into infinite loop on setting state array provided by parent in props

父元素从服务器获取数组并在 props 中提供子元素以显示数组(门票)。

父元素

    render() {
        return (
            <div style={outerBoundary}>
                <ShowArray tickets={this.state.tickets}/>
            </div>
        )
    }

子元素

 render() {
    const { classes } = this.props;
    var tablePadding = {
      'padding':'1em',
    }
    this.setState({
      tickets:this.props.tickets,
    });
    return (
      <div>
        <Paper className={classes.root} style={tablePadding}>
          <Typography variant="title" id="tableTitle">
            Array Elements
          </Typography>
          {this.state.tickets && this.state.tickets.length > 0 && this.state.tickets.map((n, index) => {
            console.log(n, index)
            return (
                <TableRow> n.id </TableRow>
            );
          })}
     )
 }

我面临的问题是票 state,我使用道具的值在子元素中设置进入无限循环。

this.setState({
  tickets:this.props.tickets,
});

显示错误信息

错误信息

您不能在render函数中调用setState

this.setState({
  tickets:this.props.tickets,
});

由于setState函数导致重新渲染,因此在下一次渲染时,您将再次调用setState ,并且您需要再次重新渲染,因此这就是循环的原因

不要在渲染中设置状态。 您可以改为映射道具:

render() {
    const { classes } = this.props;
    var tablePadding = {
      'padding':'1em',
    }

    return (
      <div>
        <Paper className={classes.root} style={tablePadding}>
          <Typography variant="title" id="tableTitle">
            Array Elements
          </Typography>
          {this.props.tickets.map((n, index) => {
            console.log(n, index)
            return (
                <TableRow> n.id </TableRow>
            );
          })}
     )
 }

请从子级的render方法中删除this.setState,然后在子级组件中尝试以下操作,

static getDerivedStateFromProps(nextProps, prevState) {
   if(nextProps.tickets){
      return {
         tickets: tickets
      }
   }
}

在子组件的渲染中,

render() {
    const { classes } = this.props;
    const { tickets } = this.state;
    var tablePadding = {
      'padding':'1em',
  .
  .
  .
  .
}

尝试这个...

为了扩展其他人所说的内容,您在render方法中使用setState

看来您正在使用props更改state

this.setState({
  tickets:this.props.tickets,
});

在您的代码中,您不需要这样做,可以使用this.props. 直接代替this.state.tickets中的jsx

但是,如果您需要根据道具更新状态,则应使用getDerivedStateFromProps

这样,您可以编写这样的static方法

static getDerivedStateFromProps(props) {
    return {
        tickets: props.tickets
    }
}

getDerivedStateFromProps的返回值用于更新状态。 在这种情况下,将使用props.tickets的值更新statetickets键。

为避免无限循环,请调用useEffect并将[this.props.tickets]作为第二个参数传入。

第一个参数中的 lambda 将仅在this.props.tickets更改值时调用,限制 state 更新的次数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM