Как извлекать (выражать) данные ТОЛЬКО после того, как данные, отправленные формой (React), были успешно получены и обслужены?

#node.js #reactjs #express #axios

#node.js #reactjs #выразить #axios

Вопрос:

В настоящее время я создаю веб-приложение на основе поиска league of legends (MOBA или многопользовательская онлайн-боевая арена), которое, по сути, позволяет пользователю искать имя своего призывателя и получать общую информацию об их вводе в поиске. (Данные предоставляются собственным сторонним API игры)

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

Как мне предотвратить выполнение запроса сервера до тех пор, пока сервер фактически успешно не обслужит данные?

(сокращенный пример однокомпонентного клиента)

  • конечная точка данных вызывающего установлена на http://localhost:3001/api/summoner
  • сервер не содержит никаких дополнительных маршрутов
 const App = () => {
  const [summName, setSummName] = useState('');
  const summonerFormData = new FormData();
  //  let data;

  const findSummoner = () => {
     summonerFormData.set('summonerName', summName);
  }

  // problem here

  const data = axios.get('http://localhost:3001/api/summoner');

  // axios.get('http://localhost:3001/api/summoner')
  //   .then(res => {
  //     data = res;  
  //   });

  return (
    <div>
      <form
        method="POST"
        action="http://localhost:3001/api/summoner"
        onSubmit={findSummoner}
      >
        <input 
          value={summName} 
          name="summName" 
            onChange={e => setSummName(e.target.value)}
        />
        <button type="submit">submit</button>
      </form>

      {data !== undefined amp;amp;
        <div className="results">
          data.map(match => {
            <div>
              <p>{match.kills}</p>
              <p>{match.deaths}</p>
              <p>{match.assists}</p>
            </div>
          })
        </div>
      }
    </div>
  )
}
  

Вот репозиторий для более подробного контекста, но, пожалуйста, не стесняйтесь спрашивать, нужна ли вам дополнительная информация или у вас вообще есть какие-либо вопросы!

Я действительно ценю любую помощь, которую я могу получить!

Спасибо!

Правки:

  • Я также пытался использовать useEffect перехват, учитывая, что точка жизненного цикла, которую я пытаюсь извлечь, была бы componentDidMount , но не был совсем уверен, каким было решение. Проводим дополнительные исследования atm!

  • Закрыть, но без сигары. Запрос застревает на ‘ожидающий’.

   let data;

  const fetchData = () => {
    axios.get('http://localhost:3001/api/summoner');
  };

  useEffect(() => {
    if (summName !== '') {
      fetchData();
    }
  }, summName);
  
  • I tried putting the axios request within an async function and awaiting on the request to respond, and it seems to be working, however, the server is still receiving undefined when the client starts, which then is attempting to be fetched, never allowing the promise to be fulfilled.
 const fetchData = async () => {
  await axios
    .get('http://localhost:3001/api/summoner')
    .then(res => {
      data = res;
    })
    .catch(() => {
      console.log('error');
    });
};

useEffect(() => {
  fetchData();
}, [])

  
  • So I took the advice and recommendations from @imjared and @HS and I’m literally so close..

I just have one more problem… My data-mapping component is trying to map non-existent data before actually receiving it, giving me an error that it’s unable to map match of undefined..

   const [modalStatus, setModalStatus] = useState(false);
  const [loading, setLoading] = useState(false);
  const [data, setData] = useState({ hits: [] });
  const [summName, setSummName] = useState('');
  const [summQuery, setSummQuery] = useState('');
  const summonerFormData = new FormData();
  const prepareResults = async () => {
    await setSummQuery(summName);
  };

  const findSummoner = async () => {
    setLoading(true);
    setModalStatus(false);
    await summonerFormData.set('summonerName', summQuery);
  };

  useEffect(() => {
    const fetchData = async () => {
      if (summQuery) {
        setData({ hits: [] });
        console.log('fetching');
        await axios
          .get('http://localhost:3001/api/summoner')
          .then(res => {
            setData(res.data);
            setLoading(false);
            setModalStatus(true);
            return data;
          })
          .catch(error => {
            console.log(error);
          });
      }
    };

    fetchData();
  }, [summQuery]);
  
  • УСПЕХ! Спасибо, ребята! Вот что в итоге сработало для меня:
 const findSummoner = async () => {
  setSummQuery(summName);
};

useEffect(() => {
  setData({ hits: [] });
  summonerFormData.set('summonerName', summQuery);

  const fetchData = async () => {
    setModalStatus(false);
    setLoading(true);

    if (summQuery !== '') {
      setLoading(true);
      console.log('fetching');
      await axios
        .get('/api/summoner')
        .then(res => {
          setData({
            hits: res.data,
          });
          setError(false);
          setLoading(false);
          setModalStatus(true);
          return data;
        })
        .catch(() => {
          setError(true);
          console.log('error');
        });
    }
  };

  if (summQuery !== '') {
    fetchData();
  }

}, [summQuery]);
  

Комментарии:

1. не уверен, что правильно понял ваш вопрос. Но если вы пытаетесь перейти к заполнению данных только после возврата `axios.get()`, вы можете установить его в асинхронное ожидание.

2. @Claeusdev Привет, спасибо за совет! Итак, я попытался установить компонент как асинхронный, который ожидает запроса axios, но столкнулся с другой проблемой..

3. проверьте выборку данных с помощью перехватов. robinwieruch.de/react-hooks-fetch-data

Ответ №1:

Этот поток поможет вам лучше разрабатывать —

 1. User - input 
2. Hit - search
3. Set loading in state - true,
5. Set data in state - empty
6. Call api
7. Get data
8. Then, set data in state
6. Set loading in state - false
  

Вдоль стороны при рендеринге / возврате —

 1. if loading in the state - indicate loading.
2. if loading done( false ) and data is not empty - show data.
3. if loading done and data is empty - indicate 'not-found'.
  

Переходим к начальной части визуализации — axios.get() вызывает api, который должен быть инициирован только после отправки формы в случае. Следовательно, эта логика должна быть перемещена внутри обработчика событий.

Комментарии:

1. Спасибо! Ваш совет определенно помог мне сделать несколько прорывов! Но теперь я столкнулся с другой проблемой, описанной в моем последнем обновлении..