我正在尝试编写两个React样式的组件(使用Emotion 10),在其中一个中指定一些自定义渲染逻辑,并保留检索其“引用”的功能。
这是我的代码:
const Foo = styled(props => <div {...props} />)`
color: red;
`;
// Here I **want** to use the component selector
// https://emotion.sh/docs/styled#targeting-another-emotion-component
const Bar = styled.div`
${Foo} {
background-color: yellow;
}
`;
const App = () => {
const ref = React.useRef();
return <Bar><Foo ref={ref}>foo</Foo></Bar>;
};
ReactDOM.render(<App />, document.body);
此代码的问题是React会发出以下警告:
警告:不能为功能组件提供引用。尝试访问此引用将失败。您是要使用React.forwardRef()吗?
我们知道,情感样式的组件利用React.forwardRef
来使开发人员能够在其上使用ref
属性。但是,当您切换到自定义渲染方法后,它似乎不起作用。
然后,如果我(尴尬地 [1] )将其转换为使用React.forwardRef
,我得到的是:
const Foo = React.forwardRef((props, ref) => {
const Component = styled(props => <div {...props} />)`
color: red;
`;
return <Component {...props} ref={ref} />;
});
const Bar = styled.div`
${Foo} {
background-color: yellow;
}
`;
const App = () => {
const ref = React.useRef();
return <Bar><Foo ref={ref}>foo</Foo></Bar>;
};
ReactDOM.render(<App />, document.body);
但是,然后我得到了另一个错误:
TypeError:无法将符号值转换为字符串
我尝试使用${Foo}
的地方正在发生什么。可能是因为Emotion希望使用样式化的组件,但我现在提供了forwardRef
组件。
这里有一个CodeSandbox,可以更轻松地播放我的代码:
https://codesandbox.io/s/7ylnlovlz6
那么,实现我想要获得的目标的正确方法是什么?
[1]:我知道在渲染器中定义组件将使该组件在每个渲染器中重新渲染,但这在此情况下无关紧要。
答案 0 :(得分:2)
现在您无需执行任何操作。 Emotion会正确处理ref。 该代码将起作用。
const Foo = styled(props => <div {...props} />)`
color: red;
`;
const Bar = styled.div`
${Foo} {
background-color: yellow;
}
`;
const App = () => {
const ref = React.useRef();
return <Bar><Foo ref={ref}>foo</Foo></Bar>;
};
ReactDOM.render(<App />, document.body);