node.js - 将 React 函数式组件转换为 Hook
问题描述
在尝试学习全栈开发时,我正在尝试本教程(https://www.freecodecamp.org/news/create-a-react-frontend-a-node-express-backend-and-connect-them-together- c5798926047c/ ) 在 React-Express-Node 基本应用程序上。但是,它是使用功能组件而不是钩子编写的。我正在尝试将此部分转换为钩子:
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();
});
但 apiResponse 的 console.log 始终显示为未定义。我知道我一定做错了什么,但我无法弄清楚。
解决方案
你的尝试并不遥远。
有两个问题:
问题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>
推荐阅读
- ajax - PhoneGap Ajax API 请求没有响应
- r - 分类/天气预报
- arrays - 如何在适用时将可以是领域列表或字符串的任何内容转换为领域列表
- c# - 将输入值与 IF 语句 C# ASP.NET Razor 中的字符串进行比较
- javascript - 函数不会运行代码的第二部分我该如何解决这个问题?
- mysql - 哈希表的 MySQL 模式
- c# - 如何从excel中的合并单元格中获取范围
- javascript - “typeof window”类型上不存在属性“location”
- r - piewise线性回归集约束
- javascript - Validators.required 会引发错误,即使其中有一个值