反复获取数据丢失

时间:2018-04-30 14:46:37

标签: javascript reactjs api react-router fetch

我有一个组件,我根据之前点击的项ID来获取数据。获取成功,console.log显示正确的数据,但使用this.setState丢失数据。我在同一个组件中有componentDidUpdate和componentDidMount,不确定这是否正常,或者这两个是否正在混乱?

以下是代码:

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
      })
    })
  }

第一个渲染也会发出此警告:

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.

ComponentDidMount中的所有内容在渲染中都能正常工作,但是来自componentDidUpdate的{this.state.matchData}和{this.state.testTeam}是空的。

问题可能是ComponentDidMount重新渲染导致ComponentDidUpdate数据丢失的组件,如果是,我该如何解决?

尝试过像这样的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,
        })
      })
    }
  }

2 个答案:

答案 0 :(得分:2)

在componentDidMount上,你应该使用Promise.all。这不是你的问题,但确实更有意义。

let result = phraseObj && phraseObj.title || 'No weather title found';

看起来你的componentDidUpdate应该是一个与componentDidUpdate结合使用的getDerivedStateFromProps(这是16.3的新功能,所以如果你使用的是旧版本,请使用折旧的componentWillReceiveProps)。请参阅https://github.com/reactjs/rfcs/issues/26。另请注意,现在componentDidUpdate从getDerivedStateFromProps接收第三个参数。有关详细信息,请参阅https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html

编辑:只是为了添加更多细节。 您的状态对象应该只包含其他键,如matchIdChanged。 然后

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
  });
}

答案 1 :(得分:0)

如果您使用 react 16.3 ,则使用 getDerivedStateFromProps()生命周期函数,而不是使用componentDidUpdate()生命周期钩子反应尝试使用 componentWillReceiveProps()对于以下版本。在我看来,尽量避免使用componentDidUpdate()。

你得到的错误是因为调用了setState()函数,当你的组件以某种方式卸载时,可能有多种原因,最突出的是 -

  1. 检查此组件的渲染功能,是否根据特定条件发送null或其他内容?

  2. 检查组件的父代码,看看组件何时卸载。

  3. 或者您可以分享这些代码,以便我们为您提供帮助。

    另外尝试使用ComponentWillUnmount()进行调试,将console.log()放入其中并进行测试以获得更清晰。

    希望这有帮助,谢谢