测试中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
相关产品推荐
相关产品推荐

