You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

测试中Styled-Components子组件无法获取正确主题的问题求助

解决Styled-Components在Modal组件中无法获取ThemeProvider主题的问题

这个问题的核心原因是React Native的Modal组件会创建一个独立的React渲染树,它的子组件无法继承外部ThemeProvider提供的Context——这就是为什么你的Layout组件拿到的theme是空对象,进而报错Cannot read property 'main' of undefined。结合你使用的styled-components 4.3.2和enzyme 3.10.0版本,给你几个可行的解决方案:

方案1:模拟React Native Modal组件(最推荐)

在测试中模拟Modal,让它直接渲染子组件而不创建独立渲染树,这样外部ThemeProvider的Context就能正常传递到Layout:

import { mount } from 'enzyme';
import { ThemeProvider } from 'styled-components';
import MyComponent from './MyComponent';

const theme = { background: { main: '#fff' } };

// 模拟RN的Modal组件,直接返回子元素
jest.mock('react-native', () => {
  const originalModule = jest.requireActual('react-native');
  return {
    ...originalModule,
    Modal: ({ children, ...restProps }) => <>{children}</>,
  };
});

it('should mount successfully', () => {
  const wrapper = mount(
    <ThemeProvider theme={theme}>
      <MyComponent />
    </ThemeProvider>
  );
  
  // 可选:添加断言验证样式是否正确应用
  expect(wrapper.find('Layout').props().style.backgroundColor).toBe('#fff');
});

方案2:在MyComponent内部包裹ThemeProvider

如果你的主题需要从外部传入,调整组件结构,把ThemeProvider放到Modal内部,确保Modal的子组件能直接获取Context:

// 修改MyComponent代码
import { ThemeProvider } from 'styled-components';

const MyComponent = ({ theme }) => (
  <Modal visible>
    <ThemeProvider theme={theme}>
      <Layout> ... </Layout>
    </ThemeProvider>
  </Modal>
);

// 对应的测试代码
it('should mount successfully', () => {
  mount(<MyComponent theme={theme} />);
});

方案3:手动设置Styled-Components的Context

Styled-Components v4使用特定的Context key(__styled-components__),你可以通过enzyme的context和childContextTypes手动注入主题:

import { mount } from 'enzyme';
import PropTypes from 'prop-types';
import MyComponent from './MyComponent';

const theme = { background: { main: '#fff' } };

it('should mount successfully', () => {
  const wrapper = mount(<MyComponent />, {
    context: {
      '__styled-components__': theme,
    },
    childContextTypes: {
      '__styled-components__': PropTypes.object.isRequired,
    },
  });
});

为什么你之前的方法无效?

你尝试的wrappingComponent是把ThemeProvider包裹在整个MyComponent外层,但由于Modal的独立渲染树特性,Modal内部的Layout组件根本不在这个包裹的Context范围内,所以无法获取到主题。

内容的提问来源于stack exchange,提问作者Martin Vich

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 06:54:21