Проблема в вашем случае заключается в том, что, когда вы пытаетесь передать testFunc
дочерним элементам, использующим cloneElement
, он передается в качестве опоры для компонента переключения, который в вашем случае является дочерним или компонентом макета. И компонент switch ничего не делает с этим пропом, и он не передается компоненту AddExercise
.
Лучший способ справиться с вашим делом - избегать cloneElement
и использовать The Route непосредственно в Компоненте Layout
/**
* Router.js
*/
import { BrowserRouter, Route, Switch } from 'react-router-dom';
import Layout from './components/Layout';
import AddExercise from './pages/AddExercise';
const Router = () => (
<BrowserRouter>
<Route component={Layout} /> // This is needed so that Layout gets the Router props
</BrowserRouter>
);
export default Router;
/**
* Layout.js
*/
class Layout extends React.Component {
render() {
return (
<div>
<Switch>
<Route path="/add-exercise" render={(props) => <AddExercise {...props} testFunc: () => console.log('test function')/>} />
</Switch>
</div>
)
}
}
export default Layout;
/**
* AddExercise.js
*/
const AddExercise = ({ testFunc }) => (
<button onClick={testFunc}>Custom Btn</button>
);
export default AddExercise;
Другое решение, которое не включает в себя написание маршрутов в макете, будет включать создание другого компонента, который содержит маршруты, такие как
<BrowserRouter>
<Layout>
<ChildRoutes />
</Layout>
</BrowserRouter>
ChildRoutes.js
export const ChildRoutes = ({ testFunc }) => {
<Switch>
<Route path="/add-exercise" render={(props) => <AddExercise {...props} testFunc={testFunc}/>} />
</Switch>
}