从 useEffect 钩子中的 Promise 访问值

时间:2021-03-24 16:59:46

标签: reactjs express promise

const useOnfidoFetch = (URL) => {


useEffect(() => {
  const appToken = axios.get('http://localhost:5000/post_stuff')
   .then((response) => response.data.data.data.json_data)
   .then((json_data) => {
      const id = json_data.applicant_id;
      const token = json_data.onfido_sdk_token;
      return {id, token};
   });
  if (appToken) {
    console.log('this is working!');
    OnfidoSDK.init({
      // the JWT token you generated above
      token: null,
      containerId: "root",
      steps: [
        {
          type: 'welcome',
          options: {
            title: 'Open your new bank account',
          },
        },
        'document'
      ],
      onComplete: function (data) {
        console.log('everything is complete');
        axios.post('https://third/party/api/v2/server-api/anonymous_invoke?aid=onfido_webapp', {
          params: {
            applicant_id: appToken.applicant_id
          }
       });
      }
    });
  }
}, [URL]);

}

export default function() {
  const URL = `${transmitAPI}/anonymous_invoke?aid=onfido_webapp`;
  const result = useOnfidoFetch(URL, {});

    return (
       <div id={onfidoContainerId} />
    );
}

我已经重构了几十次,我从 appToken Promise 中取回了一些值,但我需要将该 Promise 中的 token 值提供给 token 属性在 Onfido.init({}) 内部,我需要将 id 提供给 applicant_id 属性,然后我继续获得 undefined

2 个答案:

答案 0 :(得分:0)

将整个 if(appToken){ ... } 移动到第二个 .then((json_data) => { ... }) 的主体内

像这样:

const useOnfidoFetch = (URL) => {


    useEffect(() => {
        const appToken = axios.get('http://localhost:5000/post_stuff')
            .then((response) => response.data.data.data.json_data)
            .then((json_data) => {
                const id = json_data.applicant_id;
                const token = json_data.onfido_sdk_token;
                
                // Here. This code will be executed after the values are available for id and token
                if (appToken) {
                    console.log('this is working!');
                    OnfidoSDK.init({
                        // the JWT token you generated above
                        token: null,
                        containerId: "root",
                        steps: [
                            {
                                type: 'welcome',
                                options: {
                                    title: 'Open your new bank account',
                                },
                            },
                            'document'
                        ],
                        onComplete: function (data) {
                            console.log('everything is complete');
                            axios.post('https://third/party/api/v2/server-api/anonymous_invoke?aid=onfido_webapp', {
                                params: {
                                    applicant_id: appToken.applicant_id
                                }
                            });
                        }
                    });
                }
                
                return {id, token};
            });
        
        // In here the promise is not yet finished executing, so `id` and `token` are not yet available
    }, [URL]);

};

export default function() {
    const URL = `${transmitAPI}/anonymous_invoke?aid=onfido_webapp`;
    const result = useOnfidoFetch(URL, {});

    return (
        <div id={onfidoContainerId} />
    );
}

为了更好的可读性,您还可以将 if(appToken){ ... } 块移动到一个单独的函数中,该函数将 id, token 作为参数,您可以从 promise.then 块内部调用该函数。

答案 1 :(得分:0)

如果您还需要将令牌用于其他用途,那么我建议将其存储在 useState 中,并在该状态的值发生变化时触发 OnfidoSDK.init

像这样:

const useOnfidoFetch = (URL) => {
  const [token, setToken] = useState();

  useEffect(() => {
    axios.get('http://localhost:5000/post_stuff')
      .then((response) => response.data.data.data.json_data)
      .then((json_data) => {
          const token = json_data.onfido_sdk_token;
          setToken(token);
      })
  }, [URL])

  useEffect(() => {
    if (!token) return;

    OnfidoSDK.init({
      // the JWT token you generated above
      token,
      containerId: "root",
      steps: [
        {
          type: 'welcome',
          options: {
            title: 'Open your new bank account',
          },
        },
        'document'
      ],
      onComplete: function (data) {
        console.log('everything is complete');
        axios.post('https://third/party/api/v2/server-api/anonymous_invoke?aid=onfido_webapp', {
          params: {
            applicant_id: appToken.applicant_id
          }
       });
      }
    });
  }, [token]);
}