React.js - передача реквизита детям из hoc - PullRequest
1 голос
/ 31 мая 2019

Я пытался передать некоторые реквизиты из моего 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}

Ответы [ 3 ]

4 голосов
/ 31 мая 2019

Пример рабочего 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>
0 голосов
/ 02 июня 2019

С помощью 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>
    );
}
0 голосов
/ 31 мая 2019

this.props.children представляет собой коллекцию элементов / компонентов.Таким образом, вы должны map, прежде чем позвонить cloneElement:

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