JavaScript 小谈 Stimulus.js 和 react_component 的联合使用

jicheng1014 · 2020年12月21日 · 最后由 line933200 回复于 2021年01月09日 · 753 次阅读
本帖已被管理员设置为精华贴

react 是一个处理复杂数据导致 UI 变化的一个好工具, 但是工具虽好,但是不能看啥都是钉子。 在我们常见的操作中,大多数情况交互并不是很重, 这种情况下, 用传统的 rails view 来生成界面, 实际上是个不错的选择。

平时在处理 form 的时候, 我一般不会完全用 react 处理表单, 之后 提交一个 formdata, 而是选择靠 rails 来生成 form 进行快速提交, 这样就不需要又写界面又写 rails api。

今天遇到的情况比较有典型性:

大概是表单里有一个字段存一个 json, 这个 json 本身会有复杂的配置, 有很多操作都影响着这个 json 的生成,

因为操作比较多, 于是这块当然用 react_component 比较好实现,但是个 json 本身是由表单最外层的一个 category 选择框来确定不同的模型的, 同时这两个界面模块中间还隔了一些表单的其他内容, 这些内容因为业务原因, 必须放在 category 和 react 组件的中间

平常有两种方案能解决这个问题:

  • 将整个 form 都放在 react_component 里:

这种方式其实就是走 rails api 的方式了, 但是由于这里我已经用 rails view 实现了其他表单属性的界面和校验,再改一次很麻烦

  • 在 下拉框 select change 中发起一个 srj, 返回 js 将原来的 react_component 删掉, 再重新渲染一个新的 react_component

这种方式处理起来比较简单, 即将 react_component 外层用 一个 div 包起来, 之后 change 回来的 js 先清空他, 在 render escape 一个 react_component, 这种方式倒是比较简单, 同时也不改其他的代码, 只是要多调用一下服务端,感觉有点没必要。

最后决定不如用 stimulusjs 来控制 react_component 的 props 好了,这样就可以直接通过 js 而不过后端来控制显示了。

这是相关的代码逻辑

import {Controller} from 'stimulus'

export default class extends Controller {
  static targets = ["dropdown", "metaArea"]

  connect(){
    this.changeMetaAreaAttribute();
  }

  readDropdownValue(){
    return this.dropdownTarget.value
  }

  needShowMetaArea(){
    return this.dropdownTarget.value === 'Conversations::QuestionConversation'
  }

  changeMetaAreaAttribute(){
    // 注意此处, 因为 react_component 实际存储 props 本身是string 型, 所以需要转化一下
    let json = JSON.parse(this.metaAreaTarget.dataset.reactProps)
    json["category"] = this.readDropdownValue()
    this.metaAreaTarget.dataset.reactProps = JSON.stringify(json) 
    ReactRailsUJS.mountComponents() // 注意此处, 再修改完毕之后, 需要让 React Component 重新渲染一下
  }

}

之后此处的 react_component, 需要多传一个参数,让 stimulusjs 能够指定到 target

<%= react_component "AdminMetaEditors", {init_meta: chat_task.meta, category: chat_task.category}, {data: {chat_workflow_category_target: 'metaArea'}} %>

这样就能够 react_component 和 stimulus 混用了

总结:

  1. 在前端上没必要二者选一,成年人向来是全都要。 简单逻辑上 stimulus, 复杂逻辑上 react 是一个不错的选择。
  2. react component 和 stimulus 逻辑上是可以交互的, 只需要让 stimulus 改变 react_component 的 props, 再通知 react_component 渲染即可
jasl 将本帖设为了精华贴 12月23日 19:38
需要 登陆 后方可回复, 如果你还没有账号请 注册新账号