问题
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