此功能组件具有一个调用的模板方法onChangeHandler
,该方法接受一个select
值并更新state
。问题是,state
直到第二次调用render方法之后才更新,这意味着selected选项的state
值比的值领先一步selectedRouteName
。
我知道类组件中可以使用生命周期方法来强制进行state
更新,但是,如果可能的话,我希望将其保留为功能组件。
如代码中所述,的记录状态为selectedRouteDirection
所选选项后面的一个值。如何强制将state
其更新为功能组件中的正确值?
这个问题与命名类似的问题不同,因为我的问题询问的是我用例中的实际实现,而不是询问是否可能。
import React, { useState, Fragment, useEffect } from 'react';
const parser = require('xml-js');
const RouteSelect = props => {
const { routes } = props;
const [selectedRouteName, setRouteName] = useState('');
const [selectedRouteDirection, setRouteDirection] = useState('');
//console.log(routes);
const onChangeHandler = event => {
setRouteName({ name: event.target.value });
if(selectedRouteName.name) {
getRouteDirection();
}
}
/*
useEffect(() => {
if(selectedRouteName) {
getRouteDirection();
}
}); */
const getRouteDirection = () => {
const filteredRoute = routes.filter(route => route.Description._text === selectedRouteName.name);
const num = filteredRoute[0].Route._text;
let directions = [];
fetch(`https://svc.metrotransit.org/NexTrip/Directions/${num}`)
.then(response => {
return response.text();
}).then(response => {
return JSON.parse(parser.xml2json(response, {compact: true, spaces: 4}));
}).then(response => {
directions = response.ArrayOfTextValuePair.TextValuePair;
// console.log(directions);
setRouteDirection(directions);
})
.catch(error => {
console.log(error);
});
console.log(selectedRouteDirection); // This logged state is one value behind the selected option
}
const routeOptions = routes.map(route => <option key={route.Route._text}>{route.Description._text}</option>);
return (
<Fragment>
<select onChange={onChangeHandler}>
{routeOptions}
</select>
</Fragment>
);
};
export default RouteSelect;
好吧,实际上..即使我仍然认为效果是正确的方法..您console.log
在错误的位置..fetch
是异步的,并且您console.log
在fetch
指令之后是正确的。
由于@Bernardo状态.. setState也异步,因此在您调用时getRouteDirection();
,selectedRouteName
可能仍具有先前状态。
因此要getRouteDirection();
在设置状态后进行触发。您可以使用效果并将其selectedRouteName
作为第二个参数传递(这实际上是一种优化,因此效果只有selectedRouteName
在更改后才会触发)
因此,这应该可以解决问题:
useEffect(() => {
getRouteDirection();
}, [selectedRouteName]);
但是,如果您可以提供Stackblitz或类似产品,则可以在其中重现该问题。我们绝对可以为您提供更好的帮助。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句