首页 > 解决方案 > 在 backdraftjs 中,您可以从组件内触发组件重新渲染吗?

问题描述

这是一个不起作用的 backdraftjs 组件:

class ClickButton extends Component {
    constructor(kwargs) {
        super(kwargs);
        this.clicked = false;
    }
    
    toggleButton() {
        this.clicked = !this.clicked;
    }
    
    bdElements() {
        return e.div(
            {
                className: this.clicked ? 'clicked' : '',
                bdAdvise: {click: 'toggleButton'}
            },
            'Click Me'
        );
    }
}

...也就是说,在您单击组件后,组件不会使用“clicked”类重新呈现(当然它不会)。

我可以将其更改为使用 watchables,然后从外部触发更改:

class ClickButton extends Component.withWatchables('isClicked') {    
    bdElements() {
        return e.div(
            {
                bdReflect: {
                    className: ['isClicked', c => c ? 'clicked' : '']
                },
                bdAdvise: {click: this.kwargs.toggleClick}
            },
            'Click Me'
        );
    }
}

但是有什么方法可以将这一切都保留在组件内部吗?像 ReactJS 组件状态之类的东西,您在其中进行更改并导致组件重新渲染并反映新状态?

标签: javascriptbackdraftjs

解决方案


从最后的关键问题开始:

但是有什么方法可以将这一切都保留在组件内部吗?像 ReactJS 组件状态之类的东西,您在其中进行更改并导致组件重新渲染并反映新状态?

ReactJS 组件状态是一个聚合状态:它几乎总是控制一个组件的多个方面(总是,具有非平凡的组件)。改变这些方面之一意味着改变聚合状态对象,这反过来会导致整个组件的“重新渲染”。您当然可以构建 backdraft 组件以遵循此模型,但 backdraft 并非旨在遵循此类模型(用于其他论坛中讨论的合理工程目标)。

现在转到 op 的特定示例,请注意第一个解决方案clickedClickButton. 所以,很明显,这个例子并没有“把这一切都保留在组件内部”。

我认为真正的问题是,“ClickButton提供的公共接口是什么?” 我猜 op 想要:

  1. 一个按钮
  2. 具有公共读/写布尔属性clicked
  3. clicked每次单击按钮时都会切换其属性
  4. clicked属性从 false 变为 true 时将其 DOM 类设置为“clicked”,反之亦然

这是这样一个组件:

class ClickButton extends Component.withWatchables('clicked') {
    bdElements() {
        return e.button(
            {
                bdReflectClass: ['clicked', value=>(value ? 'clicked' : '')],
                bdAdvise_click: e=>(this.clicked = !this.clicked)
            },
            'Click Me'
        );
    }
}

这是上述代码的示例,生活在笔中:https ://codepen.io/rcgill/pen/eYvrNeB

也许我没能理解这个问题的主旨,并且操作人员正在寻找方法来实现(1)私有数据,或者(2)状态突变意味着完全重新渲染。前者有规范的解决方案;你可以用 backdraft 来做后者,但如果这是你喜欢的模型,使用 ReactJS 可能会更好。


推荐阅读