Can you explain this react native code (strange arrow function in render method)?

Viewed 219

So this is some React Native code from a textbook that I'm going through, specifically it is from the render method of App.js. Of course the /* ...*/ would be filled in with actual code but it's irrelevant to my question.

<MeasureLayout>
        {layout => (
            <KeyboardState layout={layout}>
                {keyboardInfo => /* … */}
            </KeyboardState>
        )}
</MeasureLayout>

What I don't understand is what is happening with {layout => (.... So I take it that layout is an arrow function that returns this keyboardState component. So how does layout then pass itself into keyboardState's layout prop at this part <KeyboardState layout={layout}>? And why would I want to do that exactly? This whole part here is really baffling me.

3 Answers

See that {} inside render method is used for some javascript statements.

For eg.

<Text>
{personFirstNam +" " +personLastName}
</Text>

But now that in your code there is again JSX elements inside {}, it is used inside unnamed function.

i.e.

{layout => (
 ...// here you can use JSX element which will be returned into render method for UI.
)}

alternatively, if you want some operations there,

{layout =>{
 let extractData = fromSomeWhere;
 let calculatePosition = getPosition();
 return (<KeyboardState layout={layout}>
            {keyboardInfo => /* … */}
        </KeyboardState>)
}}

All of these was to just do some JS statement executions/operations inside one JSX element.

React components have props and children properties. The children property is usually a React node, but it can also be a function that returns a React node.


So how does layout then pass itself into keyboardState's layout prop at this part ?

The MeasureLayout component was created so that its children property was defined as a function instead of a React node.

And why would I want to do that exactly?

For dependency injection and as a pattern that allows for a more declarative style of programming with class-based components.


Some more in depth reading:

Topic: Functions as children

https://medium.com/merrickchristensen/function-as-child-components-5f3920a9ace9

https://codedaily.io/tutorials/6/Using-Functions-as-Children-and-Render-Props-in-React-Components

The <MeasureLayout> is passing an argument to its children as a function. and to recieve it an arrow function is used.

so, basically the code of <MeasureLayout> will be,

function MesauseLayout(props){
 //Do things 
 // layout = some result.
  return <div>{props.children(layout)}</div>
}

So, in order to receive this the child will have to be inside a function that accepts this value. So, an arrow function is used to receive this value.

<MeasureLayout>
        {layout => (
            <KeyboardState layout={layout}>
                {keyboardInfo => /* … */}
            </KeyboardState>
        )}
</MeasureLayout>

But in my opinion, using a Context/Provider with a hook will be a better option if that is possible. This is generally only used in extreme cases. There is also another option to use React.cloneElement and passing additional props. But there are tradeoffs if you have to choose between these two. Plus, There is a concept called render props which is commonly used in new libraries.

Related