Reactjs useState的问题
已编辑以包含父类 我在使用useState钩子从功能组件更改状态时遇到问题。我做错了什么?我已经用星号标出了我的api密钥。位置一和位置二工作得很好。本质上,这是我正在制作的应用程序的一部分,它使用mapbox api计算两个坐标之间的距离Reactjs useState的问题,reactjs,react-hooks,Reactjs,React Hooks,已编辑以包含父类 我在使用useState钩子从功能组件更改状态时遇到问题。我做错了什么?我已经用星号标出了我的api密钥。位置一和位置二工作得很好。本质上,这是我正在制作的应用程序的一部分,它使用mapbox api计算两个坐标之间的距离 import React, { useState, useEffect } from "react"; import { COORDS } from "./coords"; const CustomTrip = ({ locationOne, lo
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;
import React,{useState,useffect}来自“React”;
从“/COORDS”导入{COORDS};
常数CustomTrip=({
地点一,
地点二,
onLocationOneChange,
onLocationTwoChange
}) => {
常数[totalMiles,setTotalMiles]=useState(0);
异步函数fetchDistance(){
const res=等待取数(
"https://api.mapbox.com/directions-matrix/v1/mapbox/driving/" +
位置一+
";" +
地点二+
“?来源=1&注释=距离和访问\u标记=**”
);
const mapBoxObject=wait res.json();
常数米=mapBoxObject.distances[0];
常量英里数=帕塞因特(米)*0.00062137119;
设置总英里数(固定英里数(2));
控制台日志(英里到固定距离(2));
}
useffect(()=>{
fetchDistance();
},[位置一,位置二];
返回(
定制您的旅行
选择你的出发点
{Object.entries(COORDS.map)([campus,longLatt])=>(
{校园}
))}
选择你的目的地
{Object.entries(COORDS.map)([campus,longLatt])=>(
{校园}
))}
);
};
导出默认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;
类TippingPoint扩展了React.Component{
建造师(道具){
超级(道具);
此.state={
总英里数:0,
位置一:'-97.4111604,35.4653761',,
位置二:'-73.778716,42.740913'
}
this.onTotalMileChange.bind(this);
this.onlocationnechange.bind(this);
this.onLocationTwoChange.bind(this);
}
calculateTotals=()=>{….}
onTotalMileChange=(事件)=>{
this.setState({totalMiles:parseInt(event.target.value)},this.calculateTotals)
};
onLocationOnChange=(事件)=>{
this.setState({locationOne:event.target.value},this.calculateTotals)
}
onLocationTwoChange=(事件)=>{
this.setState({locationTwo:event.target.value},this.calculateTotals)
}
render(){
行程生成器
导出默认提示点;
听起来更像是,为了将totalMiles
传递回父组件,您还需要传递调用CustomTrip
的回调。现在也不需要将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]);
...
不确定您到底面临什么问题。但就useState而言,请尝试将其放在导入声明之后,CustomTrip声明之外。不是答案,只是一个建议: 这个函数感觉不属于组件内部。它基本上是一个纯函数;接受一些参数并返回一个结果。而且,至少我希望,对于相同的参数,总是相同的结果
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]);
这也可以帮助您将此逻辑移到父组件中,因为我认为它不属于您显示的那个组件。
代码段中的组件只是获取这两个位置的受控输入。除了获取这两个位置并将其转发给父组件之外,它没有任何状态和逻辑来执行任何操作
那么,它为什么要继续计算两个道具的距离,只是为了“返回”呢结果返回到提供道具的组件?甚至没有以任何方式使用该计算值。您从
控制台.log
得到了什么输出?对于我选择的最后两个坐标,我得到了1357.39,那么到底是什么问题呢?您似乎没有使用totalMiles
我在类compo中使用totalMiles是否也要附加它?状态可由组件使用或传递给子级(或回调中的父级).totalMiles应该用于什么?是不是其他地方的部分totalMiles没有被更新?处理程序会是什么样子?我现在一直在写这个。@Joshren在我的答案中添加了一个回调的实现。我实际上有一个totalMiles的更改处理程序,我使用它父组件中的其他计算,当我像您演示的那样使用它时,我得到“未处理的拒绝(TypeError):无法读取未定义的属性'value'”我的更改处理程序是:onTotalMileChange=(event)=>{this.setState({totalMiles:parseInt(event.target.value)},this.calculateTotals};@JoshWren嗯,你的onTotalMileChange
接受一个事件对象,而不是计算的“总里程”值。fetchDistance
也是一个异步函数,这意味着它隐式返回一个承诺,因此任何调用它的操作都可能会处理承诺拒绝。fetchDistance
函数采用愉快路径,因此如果您正在处理的任何操作抛出错误,它将向上传播调用堆栈,直到捕获为止。Fetch
返回一个承诺,但它不会在出错时拒绝,但是提取JSON数据可能会引发错误。如果fetch返回fetch失败,您应该首先检查res.ok
。
useEffect(() => {
fetchDistance(locationOne, locationTwo).then(setTotalMiles);
}, [locationOne, locationTwo]);