简体   繁体   English

反应获取数据丢失

[英]React fetch data getting lost

I have a component in which I fetch data based on an item ID that was clicked earlier. 我有一个组件,可以根据之前单击的项目ID获取数据。 The fetch is successful and console.log shows the correct data, but the data gets lost with this.setState. 提取成功,console.log显示了正确的数据,但是此this.setState丢失了数据。 I have componentDidUpdate and componentDidMount in the same component, not sure if this is okay or maybe these two are messing eachother up? 我在同一个组件中有componentDidUpdate和componentDidMount,不确定这是否还可以,或者这两个是否使彼此混乱?

Here is the code: 这是代码:

const teamAPI = 'http://localhost:8080/api/teams/'
const playerAPI = 'http://localhost:8080/api/playersByTeam/'
const matchAPI = 'http://localhost:8080/api/match/'

class View extends Component {

  constructor() {
    super();
    this.state = {
      data: [],
      playersData: [],
      update: [],
      team1: [],
      team2: [],
      matchData: [],
      testTeam: [],
    };
  }

  componentDidUpdate(prevProps) {
    if (prevProps.matchId !== this.props.matchId) {
      fetch(matchAPI + this.props.matchId)
      .then((matchResponse) => matchResponse.json())
      .then((matchfindresponse) => {
        console.log(matchfindresponse);
        this.setState({
          matchData:matchfindresponse,
          testTeam:matchfindresponse.team1.name,
        })
      })
    }
  }

  componentDidMount() {
    fetch(teamAPI)
    .then((Response) => Response.json())
    .then((findresponse) => {
      console.log(findresponse)
      this.setState({
        data:findresponse,
        team1:findresponse[0].name,
        team2:findresponse[1].name,
      })
    })

    fetch(playerAPI + 82)
    .then(playerResponse => playerResponse.json())
    .then(players => {
      console.log(players)
      this.setState({
        playersData:players
      })
    })
  }

The first render also gives this warning: 第一个渲染器也会发出以下警告:

Warning: Can only update a mounted or mounting component. This usually means you called setState, replaceState, or forceUpdate on an unmounted component. This is a no-op.

Please check the code for the View component.

Everything from ComponentDidMount works fine in render but {this.state.matchData} and {this.state.testTeam} from componentDidUpdate are empty. ComponentDidMount中的所有内容在渲染中都可以正常工作,但是componentDidUpdate中的{this.state.matchData}和{this.state.testTeam}为空。

Could the problem be that ComponentDidMount re-renders the component which causes the data from ComponentDidUpdate to be lost and if so, how could I fix this? 问题可能是ComponentDidMount重新渲染了导致ComponentDidUpdate中的数据丢失的组件,如果这样,我该如何解决?

Tried ComponentWillReceiveProps like this but still no luck 尝试过ComponentWillReceiveProps这样,但还是没有运气

  componentWillReceiveProps(newProps) {
    if (newProps.matchId !== this.props.matchId) {
      fetch(matchAPI + newProps.matchId)
      .then((matchResponse) => matchResponse.json())
      .then((matchfindresponse) => {
        console.log(matchfindresponse.team1.name);
        console.log(this.props.matchId + ' ' + newProps.matchId);
        this.setState({
          matchData:matchfindresponse.team1.name,
        })
      })
    }
  }

On your componentDidMount you should be using Promise.all. 在您的componentDidMount上,您应该使用Promise.all。 This isn't really your problem, but it does make more sense. 这实际上不是您的问题,但确实更有意义。

componentDidMount() {
  const promises = [
    fetch(teamAPI).then(resp => resp.json()),
    fetch(playerAPI + 82).then(resp => resp.json())
  ];
  Promise.all(promises).then(([teamData, playerData]) => {
   // you can use this.setState once here
  });
}

Looks like your componentDidUpdate should be a getDerivedStateFromProps in combination with componentDidUpdate (this is new to react 16.3 so if you are using an older version use the depreciated componentWillReceiveProps). 看起来您的componentDidUpdate应该是与componentDidUpdate结合使用的getDerivedStateFromProps(这是16.3的新功能,因此,如果您使用的是旧版本,请使用已贬值的componentWillReceiveProps)。 Please see https://github.com/reactjs/rfcs/issues/26 . 请参阅https://github.com/reactjs/rfcs/issues/26 Notice too that now componentDidUpdate receives a third parameter from getDerivedStateFromProps. 还要注意,现在componentDidUpdate从getDerivedStateFromProps接收第三个参数。 Please see https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html for more details. 请参阅https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html了解更多详细信息。

EDIT: Just to add more details. 编辑:只是添加更多详细信息。 Your state object should just include other key like matchIdChanged. 您的状态对象应该只包含其他关键字,例如matchIdChanged。 Then 然后

// in your state in your constructor add matchId and matchIdChanged then
static getDerivedStateFromProps(nextProps, prevState) {
 if (nextProps.matchId !== prevState.matchId) {
   return { matchIdChanged: true, matchId: nextProps.matchId }
 }
 return null;
}

componentDidUpdate() {
  if (this.state.matchIdChanged) {
    fetch(matchAPI + this.props.matchId)
      .then((matchResponse) => matchResponse.json())
      .then((matchfindresponse) => {
        console.log(matchfindresponse);
        this.setState({
          matchData:matchfindresponse,
          testTeam:matchfindresponse.team1.name,
          matchIdChanged: false // add this
        })
      })
  }
}

instead of using componentDidUpdate() lifecycle hook of react try using getDerivedStateFromProps() lifecycle function if you are using react 16.3 , else try using componentWillReceiveProps() for below versions . 如果您使用的是React 16.3 ,请尝试使用getDerivedStateFromProps()生命周期函数,而不要使用react的componentDidUpdate()生命周期挂钩,否则请尝试对以下版本使用componentWillReceiveProps() In my opinion try to avoid the use of componentDidUpdate(). 在我看来,请尝试避免使用componentDidUpdate()。

Plus error you are getting is because, setState() function is called, when your component somehow gets unmounted, there can be multiple reasons for this, most prominent being - 加上的错误是,调用setState()函数时,以某种方式卸载组件时,可能有多种原因,其中最主要的是-

  1. check the render function of this component, are you sending null or something, based on certain condition? 检查此组件的渲染功能,是否根据特定条件发送null或其他内容?

  2. check the parent code of component, and see when is the component getting unmounted. 检查组件的父代码,并查看何时卸载该组件。

Or you can share these code, so that we might help you with this. 或者您可以共享这些代码,以便我们可以帮助您。

Plus try to debug using ComponentWillUnmount() , put console.log() in it and test it for more clarity. 另外,尝试使用ComponentWillUnmount()进行调试 ,将console.log()放入其中,并对其进行测试以更加清楚。

Hope this helps, thanks 希望这会有所帮助,谢谢

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

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