I'm transferring some props from a layout to every children. This works when the child is a direct layout's children, but it doesn't work when I wrap a layout's child in a, for example, div.
Working case:
<Layout >
<SectionA language={props.language} />
</Layout>
But it doesn't in this case:
<Layout >
<div>
<SectionA language={props.language} />
</div>
</Layout>
* When I access to props.language in <SectionA />
component, it's undefined
Here's how I'm transferring the props from the layout to its children
render(){
const children = React.Children.map(this.props.children, (child, index) => {
return React.cloneElement(child, {
language: this.state.language,
});
});
return (
{children}
)
}
This seems like a pretty good case for the useContext hook. This would allow you to pass language down as context to all children of the context provider. For example:
import React, { createContext, useContext } from 'react';
const LanguageContext = createContext();
const LanguageProvider = (props) => {
// Can set up state here if needed
return (
<LanguageContext.Provider value={'defaultLanguage'}>
{props.children}
</LanguageContext.Provider>
);
// Wrap the components that need access to the context in the provider
const App = () => {
return (
<LanguageProvider>
<Layout >
<div>
<SectionA />
</div>
</Layout>
</LanguageProvider>
);
}
// And to access that context in SectionA (or any other child)
const SectionA = () => {
const language = useContext(LanguageContext);
return (<h1>Language is {language}</h1>);
}
I'm pretty sure there is a better way to do this (probably in the layout file), but here is how I solved this problem:
First I used a second hoc to wrap and style the sectionA component:
function simpleWrapper(props) {
return(
<React.Fragment>
<div className='container'>
<SectionA language={props.language}/>
</div>
<div>
<SectionB language={props.language}/>
</div>
...
<style jsx>{`
.container {
Stuff
`}</style>
</React.Fragment>
)
}
export default simpleWrapper;
And then I transferred all props to this wrapper:
<Layout >
<SimpleWrapper language={props.language} />
</Layout>
)
Note that I'm using this approach because I have more than only 1 component inside of
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.