[英]How To Pass a Ref to a SVG Component in React
我有一個 svg 組件,聲明如下:
import {ReactComponent as Icon} from 'someplace.svg'
function SomeComponent(props){
const [someState, setSomeState] = useState(0)
const iconRef = useRef(null)
useEffect(() => {
//always prints null
console.log(iconRef.current)
}, [someState])
return <div>
<button onClick={() => setSomeState(prev => prev + 1)}>{someState}</button>
<Icon ref={iconRef}/>
</div>
}
這里的問題是 iconRef 將始終返回 null。我認為這是因為它被聲明為一個組件,因此需要將 ref 直接轉發到 svg 標簽,但我該怎么做呢?
有任何想法嗎?
我不確定這是否適用於create-react-app
,但無論如何它已經死了。
首先你需要安裝svgr 。
npm i @svgr/webpack
添加一個svgr
配置文件。
./.svgrrc.js
module.exports = {
ref: true,
}
和 webpack 配置。
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.svg$/i,
use: ['@svgr/webpack'],
},
],
},
}
如果使用next
,請在next.config.js
中插入 webpack 配置。
const webpack = require('webpack');
module.exports = {
webpack(config) {
config.module.rules.push({
test: /\.svg$/,
use: ['@svgr/webpack'],
});
return config;
},
};
然后你可以這樣做:
import Icon from "@icons/icon.svg";
const IconWithRef () => {
const ref = useRef<SVGSVGElement | null>(null);
return (
<Icon width="50" ref={ref} />
);
};
您可以檢查此沙箱以獲取工作版本。
更新
使用它,我在將 svg 路徑直接用於.css
文件時遇到了一些問題,因為 webpack 將其解析為反應組件。 我可以找到使兩者都起作用的解決方法是像這樣更改webpack
設置。
module.exports = {
module: {
rules: [
{
test: /\.svg$/i,
type: 'asset',
resourceQuery: /url/,
},
{
test: /\.svg$/i,
resourceQuery: { not: [/url/] },
use: ['@svgr/webpack'],
},
],
},
}
然后在.css
中使用svg
的路徑,例如:
.svg-background {
background-image: url('../path/to/svg/image.svg?url');
}
注意末尾的?url
查詢參數。
使用選項issuer: /\.[jt]sx?$/
,就像在文檔中一樣,對我不起作用。
這可以通過 3 個步驟解決:
setRef
傳遞給它。例子:
將 SVG 代碼抓取到組件中,如下所示:
const CloseIcon = (props) => (
<svg
width="38"
height="38"
viewBox="0 0 38 38"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<circle cx="19" cy="19" r="18" stroke="#AFAFAF" stroke-width="2"></circle>
<path
d="M13.0548 13.336L24.9868 25.9185"
stroke="#AFAFAF"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
></path>
<path
d="M24.9862 13.3365L13.0542 25.9189"
stroke="#AFAFAF"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
></path>
</svg>
)
export default CloseIcon
然后,在使用此圖標的父組件中,設置其 ref 屬性,例如:
...
const closeIconRef = createRef()
...
<CloseIcon
style={{ position: 'absolute', top: 18, right: 18, cursor: 'pointer' }}
setRef={closeIconRef}
/>
然后將setRef
添加到 SVG 組件中的標簽:
const CloseIcon = ({ setRef }) => (
<svg
ref={setRef}
width="38"
height="38"
viewBox="0 0 38 38"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
...
你完成了!
*要記住的重要一點:子節點仍然是非引用的,所以如果在命中的路上沒有形狀,它就可以工作。 您可以為每個孩子附加一個參考。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.