Feliz: [<reactcomponent>]与React更新中的React.functionComponent</reactcomponent>

创建于 2020-11-25  ·  10评论  ·  资料来源: Zaid-Ajaj/Feliz

朋友你好,

作为幼稚的想成为前端开发人员,我遇到了有趣的行为:

根据您的文档,我更喜欢使用React.functionComponent创建组件,因为我还可以指定组件名称以进行更好的调试。 有趣的事情带有反应刷新。

这样的代码在进行任何代码更改时总是会触发整个页面的重新加载:

let subView = React.functionComponent("SubView", fun () ->
    Html.text "Hello from sub"
)

let topView = React.functionComponent("TopView", fun () ->
    Html.div [ Html.div "Hello from top"; subView () ]
)

image

但是将根组件与[<ReactComponent>]会使所有刷新工作得很好,而无需进行完全刷新。

let subView = React.functionComponent("SubView", fun () ->
    Html.text "Hello from sub"
)

[<ReactComponent>]
let topView () = Html.div [ Html.div "Hello from top"; subView () ]

是虫子吗? 是花哨的黑色领带又名功能中的错误吗? 都是我的错,因为我没有得到ReactComponent属性和React.functionComponent函数之间的区别吗? 😄

感谢您提供任何帮助以更好地理解。

question

最有用的评论

哇! 只是...哇! 愚蠢的人用三张A4纸质的问题和解释来问愚蠢的问题和聪明的人答案。 🤯,你只是摇滚,伙计! 非常感谢! ❤️现在我明白了,它将开始使用Attribute来代替。

是否仍然建议以某种方式命名组件(就像我们使用React.functionComponent的第一个参数所做的那样),或者对于属性方法而言,这不再是必需的吗?

所有10条评论

该属性将是将来使用的方式,并且对于React-Refresh起作用是必需的。 至少是这样的,但是我认为@ Zaid-Ajaj可以解决这个问题,所以没有区别吗?

嗨,罗马,

这是一个非常好的问题,没有一个简短的答案,我们开始吧。

尽管一旦我在家解决了互联网问题,我将再次恢复流媒体播放,并在其中详细说明ru

根据您的文档,我更喜欢使用React.functionComponent创建组件,因为我还可以指定组件名称以进行更好的调试。 有趣的事情带有反应刷新。

首先,我想指出的是,文档处于一种过渡的不幸状态:基本上已经过时了最新的Feliz和[<ReactComponent>]善良,直到我们解决了编译器插件问题并稳定了Fable使用的AST为止。 我要说的是文档支持React.functionComponent ,如果您使用的是寓言3,则应该改用[<ReactComponent>]

这与如何生成Javascript代码有关。 现在考虑这段React代码:

const App = ({ title }) => {
  return (
    <h1>{title}</h1>
  )
};

<App title="My React Application" />

这JS(实际上是JSX)desugars到下面的JS代码

import { createElement } from 'react'

const App = ({ title }) => {
  return createElement("h1", null, title);
};

// <App /> compiles to a call to createElement
createElement(App, { title: "My React Application" })

请务必注意,通过<App ... />初始化App组件已编译createElement从JS调用

这很重要,原因有两点:

  • 它将组件的定义创建分开
  • 它允许App是一个静态值(保留使用React的身份)

现在,实现React.functionComponent方式对React来说是“不好的”,因为它一次又一次地将定义和创建结合在一起。 此F#代码

let app React.functionComponent("App", fun (props: {|  tite: string |}) -> Html.h1 props.title)

有点像说

let app = 
  let render(props: {|  tite: string |}) = 
    let renderFn props= Html.h1 props.title
    createElement(renderFn , props)
  render.displayName <- "App"
  render

现在,这是“不好的”,因为createElement会呈现一个在每次调用时动态定义的组件,并且会更改函数的displayName而不是使用函数名称本身。

React.functionComponent使用的语法语法不会影响React的运行时行为,这就是为什么我们能够毫无问题地使用它来构建React应用程序的原因。 当围绕React应用程序的工具开始分析生成的代码时,问题开始蔓延:webpack,babel,react-refresh都是查找生成代码的工具,在这里和那里注入一些魔力,使得可以进行热模块替换,但是使用React.functionComponent这是不可能的,因为在您编写JS时生成的代码与通常构建React应用程序的方式不符,并且许多围绕React的工具都基于根据标准编写代码这一事实进行假设比起工具产生的反应。

解决这些问题的方法是寓言3,其中允许我们通过编译器插件来自定义代码的编译。 如果您在寓言3中考虑此F#Feliz代码

[<ReactComponent>]
let app (title: string) = Html.h1 title 

app "My  React Application"

然后将其编译为与该JS等效的代码(不完全是因为有更多的魔力)

const App = (props) { 
   const title = props.title
   return createElement("h1", null, title)
}

createElement(App, { title: "My  React Application" })

现在,已将此生成的代码自定义为看起来像React工具所期望的那样:

  • 功能组件的定义和创建是分开的
  • 组件被定义为大写(是的,这也是必需的,编译器插件会自动重写该定义)
  • 输入参数会自动翻译成React道具

这种组合使React刷新工作正常进行,并且通过扩展使Feliz的体验真正接近于本机JS或TS的体验。 我希望这可以消除混乱。 如果您还有其他问题,请告诉我😉

哇! 只是...哇! 愚蠢的人用三张A4纸质的问题和解释来问愚蠢的问题和聪明的人答案。 🤯,你只是摇滚,伙计! 非常感谢! ❤️现在我明白了,它将开始使用Attribute来代替。

是否仍然建议以某种方式命名组件(就像我们使用React.functionComponent的第一个参数所做的那样),或者对于属性方法而言,这不再是必需的吗?

现在我明白了,它将开始使用Attribute来代替。

惊人的! 如果遇到任何问题,请允许我😉-现在唯一需要注意的问题是使用记录类型,因为输入道具对于React-refresh来说有点问题,因此您可以使用匿名记录代替或使用原始参数。 我希望这个问题能尽快解决,这样我就可以[<ReactComponent>]没有任何警告的情况下记录

是否仍然建议以某种方式命名组件(就像我们使用React.functionComponent的第一个参数所做的那样),或者对于属性方法而言,这不再是必需的吗?

不,唯一的要求是将组件编译为大写值,这是[<ReactComponent>]对函数定义执行的操作之一:smile:您可以在此处实现

@Dzoukr为您的

@Shmew是的,但是在ReactComponent构造函数上没有用于添加此类名称的重载,这就是为什么要问这个问题。

因此,继续[<ReactComponent>] vs functionComponent问题:钩子!

我有一个需要初始化某些状态的组件。 幸运的是,我们有许多可用的精美钩子! 我这样写:

[<ReactComponent>]
let Entrypoint() =
    let drawing, updateDrawing = React.useState(Deferred.HasNotStartedYet)
    let loader = React.useDeferredCallback((fun () -> loadDrawing()), updateDrawing)

    React.useEffect(loader, [||])
    // etc

las,当我尝试运行此命令时,我的控制台很难过,并且充满错误:

Uncaught Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.
    React 

我已经完成了上面的react调试步骤; 似乎都不是真的。 这应该工作吗? 这是寓言3唯一的东西吗? (我仍在使用寓言2。)

我的理解是reactcomponent属性需要寓言3才能工作,因为它是寓言3编译器插件

@landy啊,那一定可以。 Lemme获得Fable 3的支持,一分钟后会报告

嘿! 是的,这解决了我-我使用此PR作为转换的指南。

此页面是否有帮助?
0 / 5 - 0 等级