M. Walker
M. Walker

Reputation: 613

React Native: HOC Missing state when using `onLayout`

This component renders the Placeholder & once it gets layout, this HOC updates the state and calls the child with the values.

All good so far, but when the child resizes (WillChangeSizeIn3Seconds), render is called again, but this time the state is {}.

When it calls render the second time, it is actually right before the componentWillUnmount call.

Why does the state not persist across re-renders?

// HOC

const onLayout = Placeholder =>
    class OnLayout extends Component {
        state = {}

        componentWillUnmount() {
            debugger
        }

        componentDidMount() {
            debugger
        }

        onLayout = ({ nativeEvent: { layout } }) => {
            this.setState({ layout })
        }

        render() {
            const { children, ...rest } = this.props
            const { layout } = this.state

            return layout ? (
                children(layout)
            ) : (
                <Placeholder {...rest} onLayout={this.onLayout} />
            )
        }
    }

// Usage

class TestComponent extends Component {
    render() {
        const OnLayout = onLayout(Loading)

        return (
            <View>
                <OnLayout>
                    ({(width, height)}) =>{' '}
                    <WillChangeSizeIn3Seconds width={width} height={height} />
                </OnLayout>
            </View>
        )
    }
}

Upvotes: 2

Views: 361

Answers (1)

Oblosys
Oblosys

Reputation: 15106

The problem is that the HOC application is inside a render method, which means OnLayout will be a different class on each rerender of TestComponent. This in turn causes the previous OnLayout to be unmounted and replaced by a new one, losing all state.

Some more information can be found in the React docs on HOCs: Don’t Use HOCs Inside the render Method

Upvotes: 3

Related Questions