警告:无法在尚未安装的组件上调用 setState。调用 API 时
Warning: Can't call setState on a component that is not yet mounted. When calling an API
当我尝试 运行 此代码时,向我显示了以下错误。
警告:无法在尚未安装的组件上调用 setState。这是一个空操作,但它可能表示您的应用程序中存在错误。相反,直接分配给 this.state
或在 Api 组件中定义具有所需状态的 state = {};
class 属性。
我应该怎么做才能解决这个问题?
class Api extends Component {
constructor(props){
super(props)
this.state = {
data: [],
}
}
async componentDidMount(){
this.apiCall()
}
async apiCall() {
let resp = await fetch(URL)
let respJson = await resp.json()
this.setState({data:respJson.data.statistics})
}
}
export default function App(){
const api = new Api()
api.componentDidMount()
return (
<View>
<ScrollView style={styles.center}>
<Text>{api.state.data.time}</Text>
</ScrollView>
</View>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
padding: 20,
alignItems: 'center',
padding: 15,
},
title: {
padding: 30,
},
})
在使用 Federkun 解决方案后,我得到了这个新错误,我对 JS 很陌生,所以我有点迷茫。
我尝试使用异步函数,但一直显示错误。
Failed building JavaScript bundle. SyntaxError:
C:\Users\yup\Documents\GitHub\LEARN_REACT\App.js: Unexpected reserved word 'await'. (54:19) 52 | 53 | React.useEffect(() => { > 54 | let resp = await fetch(URL) | ^ 55 | let respJson = await resp.json() 56 | setData({data:respJson.data.statistics})
Api
并不是真正的反应 Component
。没有渲染功能。而且您需要将它用作 jsx 的一部分,而不是那样。
但是,有一个可以保存状态的有用原语:钩子。
function useApi() {
const [data, setData] = React.useState()
React.useEffect(() => {
async function load() {
let resp = await fetch(URL)
let respJson = await resp.json()
setData({data:respJson.data.statistics})
}
load()
}, [])
return data
}
你可以使用它
export default function App(){
const data = useApi()
return (
<View>
<ScrollView style={styles.center}>
<Text>{data.time}</Text>
</ScrollView>
</View>
)
}
这是对@Federkun 答案的扩展,添加了一些其他有用的道具并修复了一些问题,
您可以将 useApi
挂钩重写为,
function useApi() {
const [data, setData] = React.useState(null);
const [error, setError] = React.useState(null);
const [loading, setLoading] = React.useState(false);
React.useEffect(() => {
const fetchData = async () => {
setLoading(true);
try {
let resp = await fetch('URL'); // your backend url goes here
let respJson = await resp.json();
setData(respJson);
} catch (err) {
setError(err);
} finally {
setLoading(false);
}
};
fetchData();
}, []);
return { data, error, loading };
};
并使用,
export default function App() {
const { data, loading, error } = useApi();
if (loading)
return (
<View style={styles.container}>
<Text>loading...</Text>
</View>
);
return (
<View style={styles.container}>
{data && (
<Text>{JSON.stringify(data)}</Text>
)}
{error && (
<Text>{JSON.stringify(error)}</Text>
)}
</View>
);
}
如果你还一头雾水,可以看看实际效果at this live snack
当我尝试 运行 此代码时,向我显示了以下错误。
警告:无法在尚未安装的组件上调用 setState。这是一个空操作,但它可能表示您的应用程序中存在错误。相反,直接分配给 this.state
或在 Api 组件中定义具有所需状态的 state = {};
class 属性。
我应该怎么做才能解决这个问题?
class Api extends Component {
constructor(props){
super(props)
this.state = {
data: [],
}
}
async componentDidMount(){
this.apiCall()
}
async apiCall() {
let resp = await fetch(URL)
let respJson = await resp.json()
this.setState({data:respJson.data.statistics})
}
}
export default function App(){
const api = new Api()
api.componentDidMount()
return (
<View>
<ScrollView style={styles.center}>
<Text>{api.state.data.time}</Text>
</ScrollView>
</View>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
padding: 20,
alignItems: 'center',
padding: 15,
},
title: {
padding: 30,
},
})
在使用 Federkun 解决方案后,我得到了这个新错误,我对 JS 很陌生,所以我有点迷茫。
我尝试使用异步函数,但一直显示错误。
Failed building JavaScript bundle. SyntaxError:
C:\Users\yup\Documents\GitHub\LEARN_REACT\App.js: Unexpected reserved word 'await'. (54:19) 52 | 53 | React.useEffect(() => { > 54 | let resp = await fetch(URL) | ^ 55 | let respJson = await resp.json() 56 | setData({data:respJson.data.statistics})
Api
并不是真正的反应 Component
。没有渲染功能。而且您需要将它用作 jsx 的一部分,而不是那样。
但是,有一个可以保存状态的有用原语:钩子。
function useApi() {
const [data, setData] = React.useState()
React.useEffect(() => {
async function load() {
let resp = await fetch(URL)
let respJson = await resp.json()
setData({data:respJson.data.statistics})
}
load()
}, [])
return data
}
你可以使用它
export default function App(){
const data = useApi()
return (
<View>
<ScrollView style={styles.center}>
<Text>{data.time}</Text>
</ScrollView>
</View>
)
}
这是对@Federkun 答案的扩展,添加了一些其他有用的道具并修复了一些问题,
您可以将 useApi
挂钩重写为,
function useApi() {
const [data, setData] = React.useState(null);
const [error, setError] = React.useState(null);
const [loading, setLoading] = React.useState(false);
React.useEffect(() => {
const fetchData = async () => {
setLoading(true);
try {
let resp = await fetch('URL'); // your backend url goes here
let respJson = await resp.json();
setData(respJson);
} catch (err) {
setError(err);
} finally {
setLoading(false);
}
};
fetchData();
}, []);
return { data, error, loading };
};
并使用,
export default function App() {
const { data, loading, error } = useApi();
if (loading)
return (
<View style={styles.container}>
<Text>loading...</Text>
</View>
);
return (
<View style={styles.container}>
{data && (
<Text>{JSON.stringify(data)}</Text>
)}
{error && (
<Text>{JSON.stringify(error)}</Text>
)}
</View>
);
}
如果你还一头雾水,可以看看实际效果at this live snack