情感样式的组件和React.forwardRef不能一起使用

时间:2019-03-25 17:26:39

标签: reactjs emotion

我正在尝试编写两个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]:我知道在渲染器中定义组件将使该组件在每个渲染器中重新渲染,但这在此情况下无关紧要。

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);