How does this code work ? How can a function be called inside a component?
import React from 'react'
const ThemeContext = React.createContext('blue');
const App = () =>
<ThemeContext.Provider value={'green'}>
<ThemeContext.Consumer>
{(value) => <button style={{ background: value }}>Hello Context!</button>}
</ThemeContext.Consumer>
</ThemeContext.Provider>
export default App
I am trying to understand React Context internals , While it is clear how Context/Provider/Consumer can be used I just don't seem to understand how this line actually works calling a function inside of a component
<ThemeContext.Consumer>
{(value) => <button style={{ background: value }}>Hello Context!</button>}
</ThemeContext.Consumer>
Is it possible have the same pattern work inside of a custom component? This throws a warning 'Functions are not valid as a React child.
<div>
{(value)=><span>{value}</span>}
</div>
React Functions as Child Components
So if I'm getting this right, you are basically asking how you could get a component which is in the following format:
<MyComponent>
{(name) => (
<div>{name}</div>
)}
</MyComponent>
These are called functions as children. You do it by managing the state or a variable in a component locally and you pass that state or variable to any other component in the app by implementing the children as a function in MyComponent
.
So your MyComponent
component will look something as follows:
class MyComponent extends React.Component {
render() {
return (
<div>
{this.props.children('Scuba Steve')}
</div>
);
}
}
MyComponent.propTypes = {
children: React.PropTypes.func.isRequired,
};
This allows you to reuse MyComponent
anywhere with the exact same state or variables but you could render it differently .
You would find this pattern quite a lot in libraries like react-final-form
for example, where the library maintains a state and the users can "consume" that state and render it in anyway they want.
You can read more about it at this link and at this link as well .
Understand React Context internals
The React Context Consumer children is a function instead of typical string or React Element
<ThemeContext.Consumer>
{(value) => <button style={{ background: value }}>Hello Context!</button>}
</ThemeContext.Consumer>
<div>
Hey, I'm normal JSX
</div>
The above code will be transpiled to
React.createElement(ThemeContext.Consumer, null, function (value) {
return React.createElement("button", {
style: {
background: value
}
}, "Hello Context!");
})
React.createElement("div", null, "Hey, I'm normal JSX"))
You can see that the children ( props.children
) is a function.
<div>
{(value)=><span>{value}</span>}
</div>
This code is mean that you declared a function inside <div>
. (Not calling that function any more)
<ThemeContext.Consumer>
{(value) => <button style={{ background: value }}>Hello Context!</button>}
</ThemeContext.Consumer>
This function will be called inside ThemeContext.Consumer
then your element will render
I see that it as more of a javascript question than a react specific; react components at the end the day will become a function; javascript support function as first-class, so a function can be passed to other function as arguments ( or returned as value ) hence the higher the components and context API. So your question can be roughly translated to this code snippet:
function Theme (color) { /* some code maybe */ return function Nav (TotalItems){ return `I'll render a ${color} with ${TotalItems} TotalItems`; } } let redThemed = Theme( "dark red"); let navComp = redThemed(17); console.log( navComp ); console.log( redThemed(12) ); let blueThemed = Theme( "light blue"); console.log( blueThemed(4) );
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.