22

I have a React Native View containing a Text field, and I'm using the onLayout prop to do some positional calculations which rely on the data it provides.

<View onLayout={this.calculateDimensions}>
  <Text>{this.props.content}</Text>
</View>

This works well, but there is a scenario where the content prop updates to a different string with the same character size. This results in the layout not changing and onLayout not triggering.

These positional calculations must occur each time the content prop updates.

Note: I am aware there are numerous ways to make the component update. Updating is not the same as laying out and sadly does not trigger onLayout.

cjhines
  • 1,148
  • 3
  • 16
  • 32
  • 7
    If all else fails, have you tried using `content` as `key` for `View`? An entirely new `View` component will be created every time `content` changes though, but it might be worth it depending on the use case. `` – Tholle Aug 10 '18 at 12:06
  • @CAJE Have you managed to figure this out? I'm currently trying to get onLayout event fired on a specific moment using PanResponder. Let me know if you have any insights. Thanks! – Sebastijan Dumančić Aug 30 '19 at 12:45
  • 1
    @SebastijanDumančić I'm afraid I don't have any insight beyond Tholle's hack. I had to resort to that. – cjhines Sep 13 '19 at 09:44

2 Answers2

15

You can have a unique key based on the content. whenever a key attribute of a component changes it is forcing a re-render.

Tom Slutsky
  • 684
  • 6
  • 11
-1

Method this.calculateDimensions needs to have some kind of indication, that it should be called again and fire re-render. I would recommend to use for its state or memo.

Let me show you an example with React Hooks. I'm setting for component onLayout, which using callback onComponentLayout. onComponentLayout has state componentHeight, which fire re-render whenever it's changed. So I'm able to change it dynamically if componentHeight is missing.

...
const onComponentLayout = useCallback(({nativeEvent: {layout}}) => {
   !componentHeight && setComponentHeight(layout.height);
}, [componentHeight, setComponentHeight]);
...

return (
...
    <Component
      onLayout={onComponentLayout}
    />
...
)
Jakub Kubista
  • 101
  • 10