React 获取数据丢失
Posted
技术标签:
【中文标题】React 获取数据丢失【英文标题】:React fetch data getting lost 【发布时间】:2018-10-10 16:36:42 【问题描述】:我有一个组件,我在其中根据之前单击的项目 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,
)
)
【问题讨论】:
:o 抱歉,也许我使用的 React 版本太旧了...上次我使用它时,我很确定我必须像那样合并!删除它,再次抱歉...我要深入了解一下! 看起来你应该使用componentWillReceiveProps
而不是componentDidUpdate
【参考方案1】:
在您的 componentDidMount 上,您应该使用 Promise.all。这不是你的问题,但它确实更有意义。
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
);
看起来您的 componentDidUpdate 应该是 getDerivedStateFromProps 与 componentDidUpdate 的组合(这是对 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。 那么
// 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
)
)
【讨论】:
我试过 ComponentWillReceiveProps 但结果是一样的。不过,我可能做错了什么。查看原始帖子更新以了解我做了什么。 不幸的是,我使用的是 React 16.2 版,所以我正在尝试使用 ComponentWillReceiveProps 来解决这个问题,但非常感谢您的指点。 您可以选择升级到 React 16.3。没有重大更改,而且您获得了新的上下文 API,非常好用。 我更新到 16.3 并尝试了 getDerivedStateFromProps 并立即收到此警告:警告:查看:getDerivedStateFromProps() 被定义为实例方法,将被忽略。相反,将其声明为静态方法。 只要把 static 放在它前面。我会更新答案。【参考方案2】:如果您正在使用 react 16.3,请尝试使用 getDerivedStateFromProps() 生命周期函数,而不是使用 react 的 componentDidUpdate() 生命周期钩子,否则请尝试使用 componentWillReceiveProps()对于以下版本。在我看来,尽量避免使用 componentDidUpdate()。
您遇到的另外错误是因为调用了 setState() 函数,当您的组件以某种方式被卸载时,可能有多种原因,最突出的是 -
检查这个组件的render函数,你是根据一定的条件发送null还是什么?
查看组件的父代码,看看组件什么时候卸载。
或者您可以共享这些代码,以便我们可以帮助您。
另外尝试使用 ComponentWillUnmount() 进行调试,将 console.log() 放入其中并进行测试以提高清晰度。
希望对你有帮助,谢谢
【讨论】:
以上是关于React 获取数据丢失的主要内容,如果未能解决你的问题,请参考以下文章
React Native - 使用 react-navigation 和 react-redux 在屏幕之间切换时数据丢失
react antd Form 切换Table分页后Table内Input数据丢失问题处理