【问题标题】:Recursion works weirdly with React递归在 React 中的工作很奇怪
【发布时间】:2021-05-13 00:00:07
【问题描述】:

我正在尝试使用 React 创建 Head Recursion 的可视化,但代码在这里工作得很奇怪。 Tail 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 调用该组件。谁能解释一下这里有什么问题。提前致谢。

【问题讨论】:

  • 什么是fun()
  • fun() 仅用于打印目的,与代码无关

标签: reactjs recursion


【解决方案1】:

你可以看到你的JSX转化为babel's site的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。

【讨论】:

  • 感谢您的澄清。值的打印也是从 5 到 1,每个框都是从下到上创建的。那么这段代码实际上实现了头递归还是我做错了什么,因为在尾递归的情况下,框是从上到下创建的,这正是我想要的。
猜你喜欢
  • 1970-01-01
  • 2014-08-15
  • 1970-01-01
  • 2011-05-07
  • 1970-01-01
  • 2016-07-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多