React Native onLayout with React Hooks



我想测量 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本机,您可以将useStateonLayout一起使用:

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} />;
};

最新更新