如何检查useState变量何时可用

时间:2019-10-14 10:06:44

标签: javascript reactjs ecmascript-6

我有一个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>

任何帮助将不胜感激

1 个答案:

答案 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])