1

我试图useEffect在我的 React 应用程序中使用,但也更模块化地重构事物。下面显示的是实际工作代码的核心。它驻留在 Context Provider 文件中并执行以下操作: 1. 调用 AWS Amplify 以获取最新的 Auth Access Token。Authorization2.当对 API 端点进行 Axios GET 调用时,以标头的形式使用此令牌。

这很好用,但我认为将步骤#1 移到useEffect上面自己的构造中会更有意义。此外,在这样做时,我还可以将标头对象存储为它自己的 Context 属性,然后 GET 调用可以引用该属性。

不幸的是,我现在可以从控制台日志语句中看到,当 GET 调用开始时,尚未检索到 Auth Access Token。所以重构尝试失败了。

  useEffect(() => {
    const fetchData = async () => {
      const config = {
        headers: { "Authorization":  
          await Auth.currentSession()
            .then(data => {
              return data.getAccessToken().getJwtToken();
            })
            .catch(error => {
              alert('Error getting authorization token: '.concat(error))
            })
          }};

      await axios.get('http://127.0.0.1:5000/some_path', config)
        .then(response => {
          // Process the retrieved data and populate in a Context property

        })
        .catch(error => {
          alert('Error getting data from endpoint: '.concat(error));
        });
    };

    fetchData();
  }, [myContextObject.some_data]);

有没有办法将我的代码重构为两个useEffect实例,以便第一个在第二个开始之前完成?

4

1 回答 1

1

您可以将配置对象保持在一个状态。这样,您可以将两个 fetch 调用分开,并在第一个调用完成后触发第二个调用:

const MyComponent = props => {
    const myContextObject = useContext(myContext);
    const [config, setConfig] = useState(null);

    useEffect(() => {
        const fetchData = async () => {
            const config = {
                headers: {
                    Authorization: await Auth.currentSession()
                        .then(data => {
                            return data.getAccessToken().getJwtToken();
                        })
                        .catch(error => {
                            alert("Error getting authorization token: ".concat(error));
                        })
                }
            };

            setConfig(config);
        };

        fetchData();
    }, [myContextObject.some_data]);

    useEffect(() => {
        if (!config) {
            return;
        }

        const fetchData = async () => {
            await axios
                .get("http://127.0.0.1:5000/some_path", config)
                .then(response => {
                    // Process the retrieved data and populate in a Context property
                })
                .catch(error => {
                    alert("Error getting data from endpoint: ".concat(error));
                });
        };

        fetchData();
        // This should work for the first call (not tested) as it goes from null to object.
        // If you need subsequent changes then youll have to track some property
        // of the object or similar
    }, [config]);

    return null;
};
于 2019-08-21T23:20:06.853 回答