Преобразование функционального компонента React в Hook - PullRequest
0 голосов
/ 05 марта 2020

При попытке освоить полную разработку стека я пробовал этот урок (https://www.freecodecamp.org/news/create-a-react-frontend-a-node-express-backend-and-connect-them-together-c5798926047c/) в приложении React- Express -Node basi c. Однако он был написан с использованием функциональных компонентов вместо хуков. Я пытаюсь преобразовать этот раздел в ловушку:

constructor(props) {
    super(props);
    this.state = { apiResponse: "" };
}

callAPI() {
    fetch("http://localhost:9000/testAPI")
        .then(res => res.text())
        .then(res => this.setState({ apiResponse: res }));
}

componentWillMount() {
    this.callAPI();
}

с этим в разделе рендеринга:

<p className="App-intro">;{this.state.apiResponse}</p>

Я пробовал это:

  const [apiResponse, setApiResponse] = useState();
   useEffect(() => {
     const fetchApiResponse = async () => {
       const result = await (
         'http://localhost:9000/testAPI'
       );
       setApiResponse(result);
       console.log("apiResponse " + apiResponse);
     };
     fetchApiResponse();
   });

но console.log apiResponse всегда отображается как неопределенный. Я знаю, что, должно быть, делаю что-то не так, но не могу понять

1 Ответ

1 голос
/ 05 марта 2020

Вы не за горами в вашей попытке.

Есть две проблемы:

Задача 1.

Чтобы получить тот же эффект, что и componentWillMount (примечание: это устаревший метод, используйте componentDidMount или constructor), вам нужно указать useEffect запуск только один раз при монтировании. Для этого вы даете ему пустой массив зависимостей.

useEffect(() => {
// do stuff
}, []); // empty array as second argument

Если не указать второй аргумент, эффект будет выполняться при каждом отдельном рендере.

Задача 2.

Обновления состояний асинхронные. Это означает, что вы не можете консоль журнала apiResponse сразу после обновления и ожидать, что он будет содержать новое значение.

Чтобы обойти это, просто console.log внутри тела функции за пределами ловушки.

Вот упрощенный пример:

const {useState, useEffect} = React;

const Example = () => {
  const [apiResponse, setApiResponse] = useState();
  
   useEffect(() => {
     const fetchApiResponse = () => {
       const result = 'test';
       setApiResponse(result);
       // Will not be updated
       console.log("wrong: apiResponse ", apiResponse);
     }
     fetchApiResponse();
   }, []);
   
   // Will be updated
   console.log("right: apiResponse ", apiResponse);
   
   return <span />
}

ReactDOM.render(<Example />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...