经过编辑以包含父类...
我在使用useState挂钩从功能组件更改状态时遇到问题。我在这里做错了什么?我为此加了星号。 locationOne和locationTwo运作良好。本质上,这是我正在制作的应用程序的一部分,该应用程序使用mapbox api计算两个坐标之间的距离。
import React, { useState, useEffect } from "react";
import { COORDS } from "./coords";
const CustomTrip = ({
locationOne,
locationTwo,
onLocationOneChange,
onLocationTwoChange
}) => {
const [totalMiles, setTotalMiles] = useState(0);
async function fetchDistance() {
const res = await fetch(
"https://api.mapbox.com/directions-matrix/v1/mapbox/driving/" +
locationOne +
";" +
locationTwo +
"?sources=1&annotations=distance&access_token=****"
);
const mapBoxObject = await res.json();
const meters = mapBoxObject.distances[0];
const miles = parseInt(meters) * 0.00062137119;
setTotalMiles(miles.toFixed(2));
console.log(miles.toFixed(2));
}
useEffect(() => {
fetchDistance();
}, [locationOne, locationTwo]);
return (
<div>
<center>
<h1>Customize your trip</h1>
</center>
Select your starting point
<select value={locationOne} onChange={onLocationOneChange}>
{Object.entries(COORDS).map(([campus, longLatt]) => (
<option key={campus} value={longLatt}>
{campus}
</option>
))}
</select>
Select your destination
<select value={locationTwo} onChange={onLocationTwoChange}>
{Object.entries(COORDS).map(([campus, longLatt]) => (
<option key={campus} value={longLatt}>
{campus}
</option>
))}
</select>
</div>
);
};
export default CustomTrip;
以下是父类组件的相关位:
class TippingPoint extends React.Component {
constructor(props) {
super(props);
this.state = {
totalMiles: 0,
locationOne: '-97.4111604,35.4653761',
locationTwo: '-73.778716,42.740913'
}
this.onTotalMileChange.bind(this);
this.onLocationOneChange.bind(this);
this.onLocationTwoChange.bind(this);
}
calculateTotals = () =>{ .... }
onTotalMileChange = (event) => {
this.setState({totalMiles: parseInt(event.target.value)},this.calculateTotals)
};
onLocationOneChange = (event) => {
this.setState({locationOne: event.target.value}, this.calculateTotals)
}
onLocationTwoChange = (event) => {
this.setState({locationTwo: event.target.value}, this.calculateTotals)
}
render(){
<div>
<p>Trip Builder</p>
<CustomTrip totalMiles={this.state.totalMiles} locationOne={this.state.locationOne}
locationTwo={this.state.locationTwo} onLocationOneChange={this.onLocationOneChange}
onLocationTwoChange={this.onLocationTwoChange} onTotalMileChange={this.onTotalMileChange}/>
</div>
export default TippingPoint;
答案 0 :(得分:1)
听起来更像是您还需要传递回调CustomTrip
才能将totalMiles
传递回父组件。现在也无需将totalMiles
暂时存储在状态中,可以直接在回调中传递它。
const CustomTrip = ({
locationOne,
locationTwo,
onLocationOneChange,
onLocationTwoChange,
onTotalMilesComputed
}) => {
async function fetchDistance() {
const res = await fetch(
"https://api.mapbox.com/directions-matrix/v1/mapbox/driving/" +
locationOne +
";" +
locationTwo +
"?sources=1&annotations=distance&access_token=****"
);
const mapBoxObject = await res.json();
const meters = mapBoxObject.distances[0];
const miles = parseInt(meters) * 0.00062137119;
onTotalMilesComputed(miles.toFixed(2)); // <-- passed callback
console.log(miles.toFixed(2));
}
useEffect(() => {
fetchDistance();
}, [locationOne, locationTwo]);
...
父组件现在只需要一个处理程序即可。 (如果父级是功能组件,则使onTotalMilesComputed
常量并省略this.
)
onTotalMilesComputed = totalMilage => {
// do something with totalMilage, like set/update state
}
...
render() {
...
return (
...
<CustomTrip
// ...all other passed props, locations, etc...
onTotalMilesComputed={this.onTotalMilesComputed}
/>
...
);
}
答案 1 :(得分:0)
不确定您面临的问题到底是什么。但是就useState而言,请尝试将其放在CustomTrip声明之外的import语句之后。
答案 2 :(得分:0)
不是答案,只是建议:
感觉不到此功能,因为它属于组件的 。它基本上是一个纯函数;接受一些参数并返回结果。而且,至少我希望,对于相同的参数,始终保持相同的结果
async function fetchDistance(locationOne, locationTwo) {
const res = await fetch(
"https://api.mapbox.com/directions-matrix/v1/mapbox/driving/" +
locationOne +
";" +
locationTwo +
"?sources=1&annotations=distance&access_token=****"
);
const mapBoxObject = await res.json();
const meters = mapBoxObject.distances[0];
const miles = parseInt(meters) * 0.00062137119;
console.log(miles.toFixed(2));
return miles.toFixed(2);
}
在组件内部,您只需执行以下操作:
useEffect(() => {
fetchDistance(locationOne, locationTwo).then(setTotalMiles);
}, [locationOne, locationTwo]);
这还可以帮助您将此逻辑移到父组件中,因为我认为它不属于您所显示的那个。 代码段中的Component仅仅是获得两个位置的受控输入。它没有状态,也没有逻辑,除了获得两个位置并将它们转发到父组件之外,什么也不做。
那么,为什么要逻辑计算给出给它的两个道具的距离,只是将结果“返回”给提供道具的组件呢?甚至不以任何方式使用该计算值。