我一直在尝试将一些道具从我的HOC传递给孩子们。 HOC包装响应路由器的交换机和路由。子组件中缺少道具。我使用React.CloneElement将道具添加到孩子中,但似乎不起作用
<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>
这是HOC(布局)
class Layout extends React.Component {
.....
render() {
const children = this.props.children && React.cloneElement(this.props.children, { data: 'ok' })
...
子组件没有得到数据道具,我只是得到了
{history: {…}, location: {…}, match: {…}, staticContext: undefined}
答案 0 :(得分:4)
一个有效的HOC示例鞭子将一个data
道具注入到基础组件中。
const withData = Base => () => <Base data="ok" />
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>
答案 1 :(得分:0)
this.props.children
是元素/组件的集合。因此,您必须map
才能调用cloneElement
:
return React.Children.map(this.props.children, el => (
React.cloneElement(el, { data: 'ok' });
);
答案 2 :(得分:0)
使用HOC,您可以将道具传递给直接的孩子。
如果您需要将道具传递给较深的孩子,则可能需要使用React Context API。
例如:
// 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>
);
}