为什么我的 ReactJS 组件状态更改没有触发重新渲染?
Why is my ReactJS component state change not triggering a re-render?
我有一个带有以下构造函数的 ReactJS class 组件:
constructor(props) {
super(props);
this.state = {
// Defaults (London)
latitude: 51.509865,
longitude: -0.118092,
userAddress: null
};
this.getCoordinates = this.getCoordinates.bind(this);
}
然后我尝试获取用户坐标并将它们保存到状态:
// On component initialisation, get the users location in co-ordinates and set the state accordingly
componentDidMount() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(this.getCoordinates, this.handleLocationError);
} else {
alert("Geolocation is not supported by this browser.");
}
}
getCoordinates(position) {
this.setState({
latitude: position.coords.latitude,
longitude: position.coords.longitude
})
}
我将用户坐标传递给一个子函数,该子函数在屏幕上呈现一张天气卡,其中包含用户所在位置的当前温度。
渲染函数:
render() {
(some code)
<div><CreateWeatherCard lat={this.state.latitude} long={this.state.longitude} /></div>
(some code)
}
创建天气卡片的函数将用户坐标作为道具,在 POST 请求 API 调用中使用它们,然后应该在用户当前位置显示温度屏幕
function CreateWeatherCard(props) {
const classes = cardStyles();
let [currentTemp, setCurrentTemp] = React.useState([]);
// console.log(props.lat)
React.useEffect(() => {
async function fetchData() {
const request = await axios.post('/weatheratcoords/', {
lat: props.lat,
long: props.long
});
// console.log(request);
// console.log(request.data.currentTemp);
setCurrentTemp(request.data.currentTemp);
return request;
}
fetchData();
}, []);
return
blah blah
但由于我是 运行 本地后端,我可以看到我只收到一个 API 状态构造函数的默认坐标调用。我再也没有接到更新坐标的第二个电话。我知道状态正在成功更新,因为我可以在 React 开发工具中的组件状态中看到我自己的 lat/long 坐标。
我的理解是状态变化应该触发重新渲染,这反过来应该创建一个新的 API 具有正确用户坐标的调用?有人可以帮助我理解为什么这没有发生吗?谢谢!
你的useEffect()
有问题。
你是这样写的:
React.useEffect(() => {
async function fetchData() {
const request = await axios.post('/weatheratcoords/', {
lat: props.lat,
long: props.long
});
// console.log(request);
// console.log(request.data.currentTemp);
setCurrentTemp(request.data.currentTemp);
return request;
}
fetchData();
}, []);
第二个参数为空数组,表示useEffect()
只执行一次
解决方案
当你使用 props 将值传递给子组件时,所以当 props 改变时,useEffect()
将被执行。为此,将 useEffect()
数组中的道具作为第二个参数传递。
像这样:
React.useEffect(() => {
async function fetchData() {
const request = await axios.post('/weatheratcoords/', {
lat: props.lat,
long: props.long
});
// console.log(request);
// console.log(request.data.currentTemp);
setCurrentTemp(request.data.currentTemp);
return request;
}
fetchData();
}, [props]);
我有一个带有以下构造函数的 ReactJS class 组件:
constructor(props) {
super(props);
this.state = {
// Defaults (London)
latitude: 51.509865,
longitude: -0.118092,
userAddress: null
};
this.getCoordinates = this.getCoordinates.bind(this);
}
然后我尝试获取用户坐标并将它们保存到状态:
// On component initialisation, get the users location in co-ordinates and set the state accordingly
componentDidMount() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(this.getCoordinates, this.handleLocationError);
} else {
alert("Geolocation is not supported by this browser.");
}
}
getCoordinates(position) {
this.setState({
latitude: position.coords.latitude,
longitude: position.coords.longitude
})
}
我将用户坐标传递给一个子函数,该子函数在屏幕上呈现一张天气卡,其中包含用户所在位置的当前温度。
渲染函数:
render() {
(some code)
<div><CreateWeatherCard lat={this.state.latitude} long={this.state.longitude} /></div>
(some code)
}
创建天气卡片的函数将用户坐标作为道具,在 POST 请求 API 调用中使用它们,然后应该在用户当前位置显示温度屏幕
function CreateWeatherCard(props) {
const classes = cardStyles();
let [currentTemp, setCurrentTemp] = React.useState([]);
// console.log(props.lat)
React.useEffect(() => {
async function fetchData() {
const request = await axios.post('/weatheratcoords/', {
lat: props.lat,
long: props.long
});
// console.log(request);
// console.log(request.data.currentTemp);
setCurrentTemp(request.data.currentTemp);
return request;
}
fetchData();
}, []);
return
blah blah
但由于我是 运行 本地后端,我可以看到我只收到一个 API 状态构造函数的默认坐标调用。我再也没有接到更新坐标的第二个电话。我知道状态正在成功更新,因为我可以在 React 开发工具中的组件状态中看到我自己的 lat/long 坐标。
我的理解是状态变化应该触发重新渲染,这反过来应该创建一个新的 API 具有正确用户坐标的调用?有人可以帮助我理解为什么这没有发生吗?谢谢!
你的useEffect()
有问题。
你是这样写的:
React.useEffect(() => {
async function fetchData() {
const request = await axios.post('/weatheratcoords/', {
lat: props.lat,
long: props.long
});
// console.log(request);
// console.log(request.data.currentTemp);
setCurrentTemp(request.data.currentTemp);
return request;
}
fetchData();
}, []);
第二个参数为空数组,表示useEffect()
只执行一次
解决方案
当你使用 props 将值传递给子组件时,所以当 props 改变时,useEffect()
将被执行。为此,将 useEffect()
数组中的道具作为第二个参数传递。
像这样:
React.useEffect(() => {
async function fetchData() {
const request = await axios.post('/weatheratcoords/', {
lat: props.lat,
long: props.long
});
// console.log(request);
// console.log(request.data.currentTemp);
setCurrentTemp(request.data.currentTemp);
return request;
}
fetchData();
}, [props]);