Как я могу передать реквизит от Родителя Ребенку с this.props.children? - PullRequest
0 голосов
/ 27 сентября 2018

У меня возникают трудности при попытке передать реквизиты this.props.children

У меня есть компонент MainLayout, и я хотел бы передать реквизиты this.props.children, но его дети таковы:

AppRouter.js

export default class AppRouter extends Component {

  render() {

    return (
      <HashRouter>
        <Switch>
          <MainLayout>
            <Route exact path="/" component={PubsList} />
            <Route exact path="/add-pub" component={AddPub} />
            <Route exact path="/add-pub/:id" component={AddPub} />
          </MainLayout>
        </Switch>
      </HashRouter>
    )
  }
}

MainLayout.js: я использовал React.Children и React.CloneElement для передачи реквизитов

export default class MainLayout extends Component {

 constructor(props) {
  super(props);
  this.state = {
   foo: "foo"
  };

  render() {

    return (
      <div className="container" >
        <Menu inverted color='teal' fixed="top" style={{ margin: "0", padding: "20px", borderRadius: "0", display: "block" }}>    
          <Link to="/">
            <Header as='h2' content='PandaBar' floated="left" style={{ color: "white", margin: "0" }} />
          </Link>    
        </Menu>    

        <div className="content" style={{ marginTop: "70px", overflow: "hidden" }} >    

          {React.Children.map(this.props.children, child => {
           return React.cloneElement(child, { foo: this.state.foo })
          })}    

        </div>
      </div>
    );
  }
}

Но как только мои маршруты получают реквизиты, онвыглядит так:

<HashRouter>
   <Switch>
     <MainLayout>
        <Route exact path="/" component={PubsList} foo="foo"/>
        <Route exact path="/add-pub" component={AddPub} foo="foo"/>
        <Route exact path="/add-pub/:id" component={AddPub} foo="foo"/>
     </MainLayout>
    </Switch>
</HashRouter>

Итак, как я могу передать мои реквизиты foo моему компоненту PubsList и AddPub с этой конфигурацией?

Ответы [ 2 ]

0 голосов
/ 27 сентября 2018

В примере foo prop передается неправильному компоненту (Route).

Для того, чтобы быть переданным компонентам маршрута, вместо него следует изменить маршрут component prop:

const withFoo = (Comp, foo) => props => <Comp {...props} foo={foo}/>;
...

  render() {

    return (
      ...
      {React.Children.map(this.props.children, route => {
        return React.cloneElement(route, {
          component: withFoo(route.props.component, this.state.foo)
        });
      })}    
      ...
    );
  }

Хотя использование Route render prop в качестве другого варианта ответа может быть более простым.

0 голосов
/ 27 сентября 2018
Маршрут

позволяет передавать пользовательские реквизиты компоненту, используя реквизит render вместо реквизита component.Вы передаете функцию в render реквизит, и эта функция будет вызываться с теми же реквизитами, которые обычно автоматически передаются при использовании component.Затем вы можете делать с этими реквизитами все, что захотите

Пример этого (не включая ваш компонент mainLayout) будет выглядеть так:

<Route render={(routeProps) => (
  <PubsList hello="world" {...routeProps} />
)}/>

Таким образом, вы можете использовать произвольныйреквизит на компоненты.Но тогда как позволить MainLayout диктовать, что это за дополнительные реквизиты?Там я думаю, что вам нужно изменить MainLayout, чтобы иметь собственную опору рендеринга.

render() {
  let children = null;
  if (this.props.render) {
    children = this.props.render({ foo: this.state.foo })
  }

  return (
    <div className="container" >
      <Menu inverted color='teal' fixed="top" style={{ margin: "0", padding: "20px", borderRadius: "0", display: "block" }}>    
        <Link to="/">
          <Header as='h2' content='PandaBar' floated="left" style={{ color: "white", margin: "0" }} />
        </Link>    
      </Menu>    

      <div className="content" style={{ marginTop: "70px", overflow: "hidden" }} >    
        {children}
      </div>
    </div>
  );
}

И вы бы использовали это так:

<MainLayout render={(layoutProps) => (
  <React.Fragment>
    <Route exact path="/" render={(routeProps) => 
      <PubsList {...layoutProps} {...routeProps} />
    }/>
    <Route exact path="/add-pub" render={(routeProps) => 
      <AddPub {...layoutProps} {...routeProps} />
    }/>
    <Route exact path="/add-pub/:id" render={(routeProps) => 
      <AddPub {...layoutProps} {...routeProps} />
    }/>
  </React.Fragment>
)} />
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...