我正在获取本地数据库(sqlite)中的数据并更新状态,并且出现此错误:
无法在已卸载的组件上执行React状态更新。这是> no-op,但表示您的应用程序中发生内存泄漏。要进行修复,请> componentWillUnmount方法取消所有预订和异步任务。
没有办法帮助我。
_isMounted = false;
constructor(props) {
super(props);
this.state = {
slug: "",
value: "",
cod_year: "",
months: [],
years: [],
loadingData: true,
};
}
db = openDatabase({ name: 'test.db', createFromLocation : '~my_finances.db'});
getYears = () => {
if(this.state.loadingData){
this.db.transaction((txn)=>{
txn.executeSql(
"SELECT cod, slug FROM year",
[],
(tx, res) => {
if(res.rows.length > 0){
rows = [];
for(let i=0; i<res.rows.length;i++){
rows.push(res.rows.item(i));
}
this.setState({years: rows}, {loadingData: false});
}
}
)
})
}
}
componentDidMount(){
this._isMounted = true;
this.getYears();
}
render() {
const state = this.state;
if(!state.loadingData){
const pickerItens = state.years.map((record, index) => {
<Picker.Item label={record.slug} value={record.cod}/>
})
return (
<View style={{flex: 1}} >
<ScrollView style={styles.container}>
<View style={styles.form_add}>
<Text style={styles.form_slug} > Adicionar </Text>
<TextInput
placeholder="Digite o mês..."
onChangeText={(slug) => { this.setState({slug}) }}
value={this.state.slug}
style={styles.input_add}
/>
<TextInput
placeholder="Digite o valor..."
onChangeText={(value) => { this.setState({value}) }}
value={this.state.value}
style={styles.input_add}
/>
<Picker onValueChange = {(cod_year) => {this.setState({cod_year})}}>
{ pickerItens }
</Picker>
<Button color="#7159C1" title="Salvar" onPress={() => this.addYear()} />
</View>
</ScrollView>
<Footer navigate={this.props.navigation.navigate} />
</View>
);
}else{
<Text> Loading... </Text>
}
}
答案 0 :(得分:1)
无论何时有任何任务在运行,您都可以通过向后导航来拉开屏幕,
此警告出现
您无需担心任何事情。
这是正常警告。
假设您已完成setState
的运行,请卸载所有内容。
因此,这里的系统会认为我正在做setState
,但是我没有类,这个或/和变量来做。
因此,它只是警告您所有内容均已卸载,而我无法在已卸载的组件上进行操作。
关于杀死异步任务...,
假设您将计时器设置为1分钟,并且您每对{1}进行一次on状态变量设置。
setState
现在无论您做什么,这1分钟计时器将无限运行直到您终止应用程序。
因此,系统建议您在卸载组件时取消此类任务。
let this.timerState = setTimeout(() => {
this.setState({ timer: this.state.timer + 1 });
}, 1000);
的生命周期方法clearTimeout(this.timerState)
也是如此。
所以不要打扰警告没有泄漏的东西。
答案 1 :(得分:0)
在构造函数中初始化db并将其添加到状态,如下所示:
constructor(props: Props) {
super(props);
const db = SQLite.openDatabase({
name: 'test.db',
location: 'default',
createFromLocation: '~my_finances.db',
},
() => {},
error => {
console.log(error);
}
);
this.state = {
db,
slug: "",
value: "",
cod_year: "",
months: [],
years: [],
loadingData: true,
};
}
然后在componentDidMount上获取getYears,如下所示:
getYears = () => {
const { loadinData, db } = this.state
if(loadingData){
db.transaction((txn) => {
txn.executeSql(
"SELECT cod, slug FROM year",
[],
(tx, res) => {
if(res.rows.length > 0){
let rows = [];
for(let i=0; i<res.rows.length;i++){
rows.push(res.rows.item(i));
}
this.setState({years: rows, loadingData: false});
}
})
})
}
}
componentDidMount() {
this.getYears();
}
只需按以下步骤关闭componentWillUnMount上的连接即可:
componentWillUnmount() {
const { db } = this.state;
db.close();
}
希望对您有帮助。