我想测量 REECT本机视图的大小每次渲染时,并将其保存到状态。如果元素布局不更改效果,则不应运行。
使用基于类的组件可以轻松使用,可以在其中使用onlayout。但是我在使用React Hooks的功能组件中该怎么办?
我已经阅读了有关Uselayouteffect的信息。如果那是要走的路,您是否有一个示例说明如何使用它?
我制作了称为二手含量的自定义钩。这就是我要走的范围:
const useDimensions = () => {
const ref = useRef(null);
const [dimensions, setDimensions] = useState({});
useLayoutEffect(
() => {
setDimensions(/* Get size of element here? How? */);
},
[ref.current],
);
return [ref, dimensions];
};
我使用钩子,然后将REF添加到我想测量的尺寸的视图中。
const [ref, dimensions] = useDimensions();
return (
<View ref={ref}>
...
</View>
);
我尝试调试ref.current
,但在那里没有发现任何有用的东西。我还尝试了效果钩中的MEATER((:
ref.current.measure((size) => {
setDimensions(size); // size is always 0
});
如果您喜欢更独立的版本,这是React Native的自定义挂钩版本:
const useComponentSize = () => {
const [size, setSize] = useState(null);
const onLayout = useCallback(event => {
const { width, height } = event.nativeEvent.layout;
setSize({ width, height });
}, []);
return [size, onLayout];
};
const Component = () => {
const [size, onLayout] = useComponentSize();
return <View onLayout={onLayout} />;
};
您有正确的想法,它只需要几个调整...主要是,递给元素ref并使用elementRef(不是 elementRef.current
((不是 useEffect
依赖关系阵列(。
(关于useEffect
vs useLayoutEffect
,因为您只是测量而不是突变DOM,所以我相信useEffect
是必经之路,但是如果需要的话,您可以将其换成类似的方式(
const useDimensions = elementRef => {
const [dimensions, setDimensions] = useState({ width: 0, height: 0 });
useEffect(() => {
const el = elementRef.current;
setDimensions({ width: el.clientWidth, height: el.clientHeight });
}, [elementRef]);
return [dimensions];
};
这样使用:
function App() {
const divRef = useRef(null);
const [dimensions] = useDimensions(divRef);
return (
<div ref={divRef} className="App">
<div>
width: {dimensions.width}, height: {dimensions.height}
</div>
</div>
);
}
工作代码盒在这里
编辑以添加反应本机版本:
对于React本机,您可以将useState
与onLayout
一起使用:
const App=()=>{
const [dimensions, setDimensions] = useState({width:0, height:0})
return (
<View onLayout={(event) => {
const {x, y, width, height} = event.nativeEvent.layout;
setDimensions({width:width, height:height});
}}>
<Text}>
height: {dimensions.height} width: {dimensions.width}
</Text>
</View>
);
}
作为对Matto1990的答案,并回答Kerkness的问题 - 这是一个示例自定义挂钩,提供X,Y位置以及布局大小:
const useComponentLayout = () => {
const [layout, setLayout] = React.useState(null);
const onLayout = React.useCallback(event => {
const layout = event.nativeEvent.layout;
setLayout(layout);
}, [])
return [layout, onLayout]
}
const Component = () => {
const [{ height, width, x, y }, onLayout] = useComponentLayout();
return <View onLayout={onLayout} />;
};