Обращение к обещанию доступа в обработчике кликов в React - PullRequest
0 голосов
/ 31 мая 2019

Этот сценарий использования состоит из трех этапов:
1. Сделайте вызов API, чтобы проверить, существует ли запись
2.Если запись существует, спросите пользователя, хотят ли они добавить ее в группу.
3.Если пользователь нажимает «ОК» на отображаемом модале, где мы его просим, ​​продолжите с другим запросом сети.

Я пытаюсь получить пользовательский ввод, используя модальное подтверждение, написанное в пользовательском компоненте, и на основании того, что пользователь нажимает кнопку «ОК» или «Отмена», я хочу сделать сетевой запрос.

Я не могу получить доступ к функции разрешения обещаний, даже если я назначил ее переменной, доступной для обработчика onClick.

Я уже пытался получить доступ к функции разрешения обещаний в обработчике onClick кнопки, которую нажимает пользователь. Оказывается, не определено.

getUserResponse отправляется в качестве аргумента другой функции, которая существует в отдельном файле JS, где выполняются все сетевые вызовы. Он вызывается после того, как запись была найдена в результате вызова API

let outsideResolve;
const getUserResponse = async () => {
    return await new Promise((resolve, reject) => {
      outsideResolve = resolve;
    });
  };

const confirmAddRecord = event => {
    event.preventDefault();
    //resolve the promise after the button click
    outsideResolve(); //error: outsideResolve is not a function
    };

return (
      <div>
        <p>Record Exists would you like to add them to the group?</p>
        <button onClick={confirmAddRecord}>Add Existing record !</button>
      </div>
    );


*********************************
in another file (networkCalls.js), getUserResponse is sent 
as an argument to a method called in the file summarized above
try {
    let userResponse = await getUserResponse();
    console.log(userResponse);
    //Do more stuff after the reply comes in
  } catch (error) {
    console.log(error);
  }

Я создал codeSandbox, чтобы воссоздать проблему более подробно: https://codesandbox.io/s/promisemodal-tke67

Ответы [ 2 ]

0 голосов
/ 31 мая 2019

Я считаю, что network.js должен только возвращать обещание, и эти обещания должны быть разрешены в вашем основном компоненте

import React, { useState } from "react";
import ReactDOM from "react-dom";

import { ADD_NEW_RECORD } from "./networkCalls";

import "./styles.css";

function App() {
  const [isModalOpen, setIsModelOpen] = useState(false);

  let createRecordPromsie = null;
  const createRecord = () => {
    createRecordPromsie = ADD_NEW_RECORD();
    createRecordPromsie.then(data => {
      setIsModelOpen(true);
    });
  };

  const getUserResponse = new Promise((resolve, reject) => {
    resolve();
  });

  const confirmAddRecord = event => {
    event.preventDefault();
    //resolve the promise after the button click
    console.log("Added Existing record");
    getUserResponse.then(data => {
      setIsModelOpen(false);
    }); //this turns out to be undefined
  };

  const renderModal = () => {
    return (
      <div>
        <p>Record Exists would you like to add them to the group?</p>
        <button onClick={confirmAddRecord}>Add Existing record !</button>
      </div>
    );
  };

  return (
    <div className="App">
      <p>Add record by pressing this button</p>
      <button onClick={createRecord}>Create record </button>
      {isModalOpen ? renderModal() : ""}
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

* +1003 * Network.js
export const ADD_NEW_RECORD = async () => {
  //checking from an API of record exists

  return new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log("Record Exists");
      resolve("Record Exists");
    }, 1000);
  });
};
0 голосов
/ 31 мая 2019

Если я вас правильно понял - основная проблема, с которой вы столкнулись, это получение доступа к информации из вашего исходного (check if user exists) вызова API. На основании этой return информации вы хотели предпринять другое действие.

Пожалуйста, посмотрите мое решение вашей проблемы (проверено на вашем codesandbox). Вот его ответвление с реализацией (https://codesandbox.io/s/promisemodal-z2r5i)

index.js ниже

import React, { useState } from "react";
import ReactDOM from "react-dom";

import {
  ADD_NEW_RECORD,
  MAKE_API_CALL_AFTER_RECORD_CHECK
} from "./networkCalls";

import "./styles.css";

function App() {
  const [isModalOpen, setIsModelOpen] = useState(false);
  const [infoFromCreateRecord, setInfoFromCreateRecord] = useState({});

  const createRecord = () => {
    ADD_NEW_RECORD(isModalOpen, setIsModelOpen, setInfoFromCreateRecord);
  };

  const confirmAddRecord = () => {
    MAKE_API_CALL_AFTER_RECORD_CHECK(infoFromCreateRecord);
    setIsModelOpen(false);
  };

  const renderModal = () => {
    return (
      <div>
        <p>Record Exists would you like to add them to the group?</p>
        <button onClick={confirmAddRecord}>Add Existing record !</button>
      </div>
    );
  };

  return (
    <div className="App">
      <p>Add record by pressing this button</p>
      <button onClick={createRecord}>Create record </button>
      {isModalOpen ? renderModal() : ""}
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

networkCalls.js ниже

export const ADD_NEW_RECORD = (
  isModalOpen,
  setIsModalOpen,
  setInfoFromCreateRecord
) => {
  //checking from an API of record exists

  const checkIfRecordExists = new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log("Record Exists");
      resolve("Record Exists");
    }, 1000);
  });

  //record exists, ask the user if they want to add them to the group
  checkIfRecordExists.then(() => {
    setInfoFromCreateRecord({
      importantInfo: "record does exits"
    });
    setIsModalOpen(!isModalOpen);
  });
};

export const MAKE_API_CALL_AFTER_RECORD_CHECK = infoFromCreateRecord => {
  // do some stuff with the info from the first API call

  const doSomethingAfterRecordCheck = new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log(infoFromCreateRecord);
      resolve("User got added to the group!");
    }, 1000);
  });

  doSomethingAfterRecordCheck.then(() => {
    console.log("do something after adding the user to the group");
  });
};
...