React.js - passing props to children from hoc

笑着哭i 提交于 2021-02-10 17:35:34

问题


I have been trying to pass some props from my HOC to children. the HOC wraps react router switch and route. The props are missing in the child component. I make use of React.CloneElement to add the props to the children but do not seem to work

<BrowserRouter>
<Layout>
        <React.Suspense fallback={loading()}>
          <Switch>
            <Route exact path="/" component={Login} />
            <Route path="/dashboard" component={Home} />
            <Route path="/tickets" component={Tickets} />

          </Switch>
        </React.Suspense>
      </Layout>
    </BrowserRouter>

this is the HOC(layout)

class Layout extends React.Component {
   .....

    render() {
        const children = this.props.children && React.cloneElement(this.props.children, { data: 'ok' })
...

the child component do no get the data prop, I get just this

{history: {…}, location: {…}, match: {…}, staticContext: undefined}

回答1:


A working HOC example that injects a data prop into the base component.

/* HOC */
const withData = Base => () => <Base data="ok" />

/* Component */
class Router extends React.Component {
  render() {
    return this.props.data;
  }
}
 
const RouterWithData = withData(Router); // export default withData(Router);

ReactDOM.render(<RouterWithData />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>



回答2:


this.props.children is a collection of elements/components. So, you have to map before calling cloneElement:

return React.Children.map(this.props.children, el => (
    React.cloneElement(el, { data: 'ok' });
); 



回答3:


With HOC, you can pass props to direct children.

If you need to pass props to deeper children, you may need to use the React Context API.

For example :

// LayoutContext.js
import React from 'react';

/**
 * Create and initialize a context for the Layout component
 */
export default React.createContext({
    data: null,
});
// Layout.js
import React from 'react';
import LayoutContext from './LayoutContext';

/**
 * The Layout component which injects the context
 * All children can consume the context
 */
export default function Layout({ children }) {
    // This is where you set your data
    const data = 'my-value';

    return (
        <LayoutContext.Provider value={{ data }}>
            {children}
        </LayoutContext.Provider>
    );
}
// SomeChild.js
import React from 'react';

/**
 * How you can consume the context in any child declared in the Layout component
 * Here we are using the `useContext` hook but it works the same by using a Consumer
 */
export default function SomeChild() {
    const { data } = React.useContext(LayoutContext);

    // Do whatever you want with the data
}
// App.js
import React from 'react';
import Layout from './Layout';

export default function App() {
    return (
        <BrowserRouter>
            <Layout>
                {/* Any component in this tree can use the LayoutContext */}
            </Layout>
        </BrowserRouter>
    );
}


来源:https://stackoverflow.com/questions/56392374/react-js-passing-props-to-children-from-hoc

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!