【问题标题】:Styled-component object can't observe mobx changesStyled-component 对象无法观察 mobx 的变化
【发布时间】:2026-01-25 06:05:02
【问题描述】:

我希望styled-components 生成的 HOC 在其属性之一发生更改时重新渲染。我正在使用 MobX 进行更改检测。

这不会响应更改,我想我明白为什么。问题是是否有一个简单的解决方法可以让它发挥作用。

const DemoComponent = observer(styled.div`
  background-color: ${props => props.myObject.myObservableIsTrue ? 'red' : 
'green'};
`);

【问题讨论】:

    标签: javascript mobx styled-components mobx-react


    【解决方案1】:

    这个小sn-p很难判断,但我的一个猜测是你没有注入任何商店,所以目前没有商店连接到你的组件。

    这是一个简单的例子,说明我如何在 mobx 中使用 styled-components,如果有帮助的话:

    已编辑: 我已经更新了代码示例。

    你知道容器/展示模式吗? 这是缺失的环节。

    为了尽量减少渲染 您需要将有状态的组件彼此分开。 将它们分散到一个容器组件(又名 Dumb Components)

    通过这种方式,您可以分离状态关注点并仅呈现具有更改状态的组件。

    更新: https://codesandbox.io/s/zxx6o2pq3l

    【讨论】:

    • 我的 sn-p 只是一个简化的例子。我编辑了您的示例以再次演示该问题:react-shubzp.stackblitz.io。关键是,在您的示例中,当颜色更改时,整个 App 会再次呈现。我想避免这种情况,只渲染Wrapper
    • 是的,我正在尝试减少渲染次数。在您的示例中查看OtherComponent。每次单击“更改颜色”按钮时,它都会重新渲染。我们可以同意吗?但这太过分了——渲染Wrapper 就足够了。所以我正在努力实现这个目标。在我的示例 stackblitz.com/edit/react-shubzp 中,“更改颜色”不起作用。我的问题是是否可以在不更改传递给 Wrapper 的道具的情况下使其工作。
    • 看这里:codesandbox.io/s/zxx6o2pq3l stackblitz 崩溃了,所以我无法更新
    【解决方案2】:

    对不起!!!有点骇人听闻的工作,但尝试将您的整个代码带入 @inject("store") 类:

    import React from "react";
    import { observer, inject } from "mobx-react";
    import styled, { css } from "styled-components";
    
    @inject("store")
    @observer
    export default class OtherComponent extends React.Component {
    
      render() {
        const MyWrapper = (store) => {
          const Wrapper = styled.div`
      border: 1px solid black;
      display: flex;
      justify-content: space-between;
      color: ${({ color }) => color};
      border: 2px solid ${({ color }) => color || "black"};
      padding: 10px;
      margin-bottom: 10px;
    `;
          return (
            <Wrapper {...store}>
              styled-component
            <button onClick={store.changeColor}>change color</button>
            </Wrapper>
          );
        }
        const { store } = this.props;
        return (
          <div>
          {
              MyWrapper(store)
          }
          </div>
        );
      }
    }
    

    Mobx 实际上是这样读的:@inject("store") @observer export default class...

    所以它实际上是扩展组件的扩展;只有包装的变量才会适用!

    【讨论】:

    • 很好,但它有点作弊:) 通过在 OtherComponent 渲染函数中声明 Wrapper ,您将使其在其他地方完全无用。所以 Wrapper 现在不是一个“真正的”组件。
    • @gamliela 谢谢!我的意思是仅仅将 Wrapper 带入注射。然后你用“OtherComponent”替换“Wrapper”,然后从“./WrapperComponent”导入Wrapper。Mobx 会自动从存储中更新组件;因此,你不必传递任何参数。
    • 哦,我现在明白你的意思了。是的,我想这是有效的,虽然效率不高,我不认为这是一个“简单的解决方法”。由于您每次渲染都创建一个新的组件类,我不确定这种方法是否实用。
    最近更新 更多