reactjs - 递归在 React 中的工作很奇怪
问题描述
我正在尝试使用 React 创建Head Recursion的可视化,但代码在这里工作得很奇怪。使用尾递归,行为与预期一致,但使用头递归,它超越了递归调用并从下到上打印数字,但最先打印底部的数字。(尝试使用 setState 进行延迟打印。)以下是相同的代码。
import React from 'react'
const Box = (props) => {
const [loading, setLoading] = React.useState(true)
var n = props.num
// setTimeout(() => {
// setLoading(false)
// }, 1000)
// if (loading) {
// return <h1></h1>
// }
return (
<div style={{
marginLeft: n * 40,
marginTop: 40
}}>
{n > 0 ? <> <Box num={n - 1} /> {console.log(`Called with n = ${n}`)} <div style={{
width: 300,
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-evenly',
border: '1px solid black'
}}>
<h1>{n}</h1>
<h1>fun({n - 1})</h1>
</div>
</> : null}
</div>
)
}
export default Box
执行时,console.log( Called with n = ${n}
)会在以 n-1 递归调用 Box 后立即被调用。(我猜这不应该发生,因为它应该完成递归调用,然后它应该控制台记录值以相反的方式记录)。我用 n = 5 调用该组件。谁能解释一下这里有什么问题。提前致谢。
解决方案
你可以看到你的 JSX 转化为 babel 的站点的 JS ,(这是浏览器实际执行的)。
对于您的组件,它变成了这样,
import React from 'react';
const Box = props => {
const [loading, setLoading] = React.useState(true);
var n = props.num; // setTimeout(() => {
// setLoading(false)
// }, 1000)
// if (loading) {
// return <h1></h1>
// }
return React.createElement("div", {
style: {
marginLeft: n * 40,
marginTop: 40
}
}, n > 0 ? React.createElement(React.Fragment, null, " ", React.createElement(Box, {
num: n - 1
}), " ", console.log(`Called with n = ${n}`), " ", React.createElement("div", {
style: {
width: 300,
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-evenly',
border: '1px solid black'
}
}, React.createElement("h1", null, n), React.createElement("h1", null, "fun(", n - 1, ")"))) : null);
};
export default Box;
看这个你可以看到console.log
被调用并且返回值被传递给React.CreateElement
即console.log
递归调用之前发生的事情,这就是你看到日志从n = 5到n = 1的原因。
推荐阅读
- ruby-on-rails - CORS 开发政策阻止的所有请求
- angular - VSCode 调试器只是坐在那里,什么都不做
- android - 将 DFP 添加到我的应用程序 android 时发生崩溃
- javascript - 类型“缓冲区”不可分配给类型“BlobPart”
- c# - 如何为 properties.resources."name" 使用字符串而不是“name”
- ruby-on-rails - RSpec 会话控制器 - 具有无效参数的用户没有设计
- c - C、将字符串分成两半
- c++ - 基本类型中的位数应该使用什么类型?
- python - 在 Python StatsModels OLS 输出中折叠分类特征级别
- android - Android P 的 LicenseChecker 错误