我有一个useState变量,该变量是根据已解决的Promise设置的,设置后如何访问该变量
目前,要获取正确的值,我必须使用setTimeout函数,只是想知道是否有更好的方法来做到这一点。
const FlagScreen = ({ t, i18n, history }) => {
const [flagAvailability, setFlagAvailability] = useState([]);
const [showFlags, setShowFlags] = useState([]);
useEffect(() => {
let flagsAvailable = [];
for (let [key, value] of Object.entries(flags)) {
if (key.indexOf(i18n.language) !== -1) {
for (const v of value) {
checkForAvailableAgent(`sales_${v}`, LINK_TO_STUDIO, SERVICE_ID)
.then(res => {
flagsAvailable[v] = res;
// Sets the flags availability i.e de: false, en: true
setFlagAvailability(flagsAvailable);
})
.catch(error => {
console.log("an error happened.");
});
}
}
}
}, [i18n.language]);
useEffect(() => {
//the value of flagAvailability is not available yet, I have to set a timeout function for
// 3 seconds for it to be available
console.log("flag availability: ", Object.entries(flagAvailability));
for (let [k, v] of Object.entries(flagAvailability)) {
console.log("key is: ", k);
if (v === true) {
setShowFlags(k);
}
}
}, [flagAvailability]);
}
<Container className="h-100">
<Row className="h-45 mt-5 text-center">
{ALL_STUDIOS_FLAGS.filter(item => {
return showFlags.includes(item);
}).map((item, index) => (
<Col key={index}>
<img
src={require(`../assets/flags/${item}.png`)}
alt={`${item} flag`}
/>
<span>{item.toUpperCase()}</span>
</Col>
))}
</Row>
任何帮助将不胜感激
答案 0 :(得分:0)
第一个useEffect中的setFlagAvailability(flagsAvailable);
仅会更新第二个渲染中的flagAvailability的值
第一个渲染中的第二个useEffect将仅获得flagAvailability的初始值(我知道它像一个圆)
每个渲染器都有其自己的useEffect和useState
解决方案之一是通过创建这样的useRef标志来跳过setShowFlags useEffect中的第一个渲染
const ref = useRef(false)
const [flagAvailability, setFlagAvailability] = useState(true);
const [showFlags, setShowFlags] = useState(true);
useEffect(()=> {
if(ref.current){
...
setShowFlags();
ref.current = false;
}
},[flagAvailability])
useEffect(() => {
...
setFlagAvailability();
ref.current = true
},[i18n.language])
或者您可以简单地将flagAvailability更改为useRef,因为refvalue始终是新值。
const flagRef = useRef([]])
const [showFlags, setShowFlags] = useState(true);
useEffect(() => {
flagRef.current = flagsAvailable
},[i18n.language])
useEffect(()=> {
for (let [k, v] of Object.entries(flagRef.current)) {
setShowFlags();
}
},[showFlags])