【问题标题】:Passing data from child to parent , but unable to setState将数据从子级传递给父级,但无法设置状态
【发布时间】:2021-06-15 03:30:48
【问题描述】:

所以,我正在尝试将数据从子组件传递到父组件。我能够通过使用道具来做到这一点,并且能够使用 console.log 打印数据。但是,当我尝试使用来自子组件的这些数据在父组件中设置状态时。我陷入更新状态的无限循环,导致错误“超出最大更新深度。当组件在 componentWillUpdate 或 componentDidUpdate 内重复调用 setState 时,可能会发生这种情况。React 限制嵌套更新的数量以防止无限循环。”

我的代码如下

父组件

import React, { Component } from 'react'
import TagsPaper from './tagsPaper'
import CurrentTagPaper from './currentTagPaper'
import ApiCall from './Backend/apiCall';

export default class Tags extends Component {
    constructor(props) {
        super(props);
        this.state = {
            tags: ["apple"],
            toUpdate: true,
        };
    }

    componentDidMount() {

    }
    getTags = (e) => {

        const array = e;
        console.log(array)
        this.setTags(array)
        return array
    }
    setTags(e) {
        this.setState({
            tags: e
        })
    }

    render() {

        return (
            <div >
                <p>
                    Get recommendations for articles that matches your
                    interests when you follow more tags:
                </p>
                <b>
                    You are following
                </b>

                <TagsPaper></TagsPaper>
                <b>
                    From this article
                </b>
                {/* pass Tag array name here*/}
                <CurrentTagPaper tagArray={this.state.tags} />
                <ApiCall getTags={this.getTags} />
            </div>
        )
    }
}

子组件

import React, { Component } from 'react';
import '../App.css';

export default class ApiCall extends Component {
  constructor(props) {
    super(props);
    this.state = {
      response: '',
      post: '',
      responseToPost: '',
      tags: this.props.tags
    };
    this.sendTags = this.sendTags.bind(this);
  }

  componentDidMount() {
   this.getTagApi()
  }

  getTagApi(){
    this.callApi()
    .then(res => this.setState({ response: res.express }))
    .catch(err => console.log(err));
  }

  callApi = async () => {
    const response = await fetch('http://localhost:5000/api/scrap');
    const body = await response.json();
    if (response.status !== 200) throw Error(body.message);
    return body;
  };
  sendTags = (value) => {
    this.props.getTags(value);
  }

  handleSubmit = async e => {
    e.preventDefault();
    const response = await fetch('http://localhost:5000/api/forms', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ post: this.state.post }),
    });
    const body = await response.text();

    this.setState({ responseToPost: body });
  };

  render() {
    let tagArray = [...this.state.response];
    this.sendTags(tagArray);

    return (
      <div className="App">
        {/* {tagArray.map(e => <p key={e}>{e}</p>)} */}

        <form onSubmit={this.handleSubmit}>
          <p>
            <strong>Post to Server:</strong>
          </p>
          <input
            type="text"
            value={this.state.post}
            onChange={e => this.setState({ post: e.target.value })}
          />
          <button type="submit">Submit</button>
        </form>
        <p>{this.state.responseToPost}</p>
      </div>
    );
  }
}

【问题讨论】:

  • 我猜这里的问题是你在render()里面使用this.sendTags(tagArray);,而不是你应该在componentDidMount()上使用它

标签: javascript reactjs react-native ecmascript-6


【解决方案1】:

当父级改变状态时,它会渲染子级。当子渲染时,它会更新父状态。有一些聪明的方法可以解决这个问题,但最终的问题是,将数据复制到父母和孩子的状态不是很习惯。

一般来说,您应该“提升”父母和孩子使用的任何状态,使其仅存在于父母中,并且这种“提升”应该在 API 调用之后立即发生。

ApiCall,你可以切换到

  getTagApi(){
    this.callApi()
    .then(res => this.sendTags(res.express))
    .catch(err => console.log(err));
  }

在您的父 Tags 组件中,您需要将父标签状态向下传递。

<ApiCall getTags={this.getTags} tags={this.state.tags} />

您的ApiTags 将只使用父母的标签。

    let tagArray = this.props.tags;

您也不会想在构建过程中将this.props.tags 复制到this.state

React 期望所有数据都有一个真实来源。如果更高级别的组件需要数据以及更低级别的组件,则应始终提升数据,例如,在数据发生更改时将其向上传递,并在每次渲染时将其作为道具向下传递。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-03-07
    • 1970-01-01
    • 2020-09-09
    • 2016-09-26
    • 2020-09-22
    • 1970-01-01
    • 1970-01-01
    • 2011-09-07
    相关资源
    最近更新 更多