简体   繁体   中英

How to transfer props to children's children in React?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM