我有一个异步功能,该功能可以从网络上获取笔记,但我遇到的问题是它试图呈现一个空数据数组,因此我收到此错误,说item.id为undefined
,因为数组为空。我尝试放置条件if (data.length === 0) return <Text>No Entries</Text>
,但是即使我console.log(data)
可以看到数据已经到达,它也不会重新呈现任何内容。数据到达后,是否有任何其他方式可以渲染?
export default class NoteList extends Component {
render() {
const { data} = this.props;
return (
<View style={styles.cardView}>
<FlatList
numColons={data.length}
data={data}
renderItem={({ item: { name, content, id } }) => {
return (
<View>
<NoteCard
name={name}
content={content}
/>
</View>
);
}}
keyExtractor={(item) => item.id}
/>
</View>
);
}
}
如何防止这种情况:
TypeError: TypeError: undefined is not an object (evaluating 'item.id')
我也收到此错误,但我认为这与管理第一个问题有关。
Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory
leak in your application. To fix, cancel all subscriptions and asynchronous tasks in %s.%s, the componentWillUnmount method,
答案 0 :(得分:1)
您遇到的问题在于,父级将数据保存在状态中。因此,您会收到有关更新已卸载组件状态的警告。有很多不同的方法可以解决此问题。我喜欢的一种方式(由于可读性)是在组件安装时使用变量。一个简单的例子:
class News extends Component {
_isMounted = false;
constructor(props) {
super(props);
this.state = {
news: [],
};
}
componentDidMount() {
this._isMounted = true;
axios
.get('https://hn.algolia.com/api/v1/search?query=react')
.then(result => {
if (this._isMounted) {
this.setState({
news: result.data.hits,
});
}
});
}
componentWillUnmount() {
this._isMounted = false;
}
render() {
...
}
}
现在,设置数据后,NoteList组件将自动更新。但是,api调用失败时会发生什么。为了防止陈旧的数据,我喜欢使用条件渲染。就像您建议的那样:
export default class NoteList extends Component {
render() {
const { data } = this.props;
if (data) {
return (
<View style={styles.cardView}>
<FlatList
numColons={data.length}
data={data}
renderItem={({ item: { name, content, id } }) => {
return (
<View>
<NoteCard name={name} content={content} />
</View>
);
}}
keyExtractor={item => item.id}
/>
</View>
);
}
}
}
答案 1 :(得分:0)
在React中执行此操作的常用方法是跟踪何时获取数据。这可以例如完成通过在您的状态下添加一个isFetching字段:
// This would be your default state
this.state = {
isFetching: false
};
然后,当您触发请求时(最好在componentDidMount中),您可以使用以下方式将isFetching设置为true:
this.setState({ isFetching: true });
最后,当数据到达时,再次将其设置为false:
this.setState({ isFetching: false });
现在,在渲染功能中,您可以执行以下操作:
render () {
return (
<div className="something">
<h3>Some content</h3>
{this.state.isFetching ? <LoadingComponent /> : (
<ul>
{listItems}
</ul>
)}
</div>
)
}
通过使用状态,您不必担心告诉组件做点什么,它会对状态的变化做出反应并相应地进行渲染。