1

我有一个具有顶级<App />组件的 React 应用程序(从 create-react-app 开始构建)。我的顶级组件看起来像这样:

<Header title={this.state.appTitle} theme={this.state.theme} />
<Switch>
  {routes.map((route, index) => <Route key={index} {...route} />)}
  <Route component={NotFound} />
</Switch>

routes是 { component:, to: } 个对象的数组)。渲染的每个组件都<Route>使用一个名为的子组件<Page>,我在其中设置标题并包装一些内容:

<Page title="About Us">
  <p>Content here</p>
</Page>

有时页面可能会使用不同的主题,我想<Header />在查看该页面时应用该主题:

<Page title="About Us" theme="alt">

我要做的是在渲染每个组件时更改appTitletheme状态。<App />做这个的最好方式是什么?使用 React 的生命周期钩子之一?改变“顶级”状态的其他方法?如果是这样,我如何通过react-router<Route>组件将操作传递给这些组件?

4

2 回答 2

2

您可以将一个函数传递给每个组件,并在每个子组件挂载时调用该函数,使用componentDidMount生命周期方法。

<Switch>
  {routes.map((route, index) => {
    const Comp = route.component;
    return <Route
      key={index}
      { ...route}
      // overwrite the component prop with another component
      component={
        (routeProps) => (
          <Comp
            {...routeProps}
            childHasMounted={() => this.setState({ name: route.name })}
          />
        ) 
      }
    />
  })}
  <Route component={NotFound} />
</Switch>

// child.js
class Child extends React.Component {
  componentDidMount() {
    this.props.childHasMounted();
  }
}
于 2018-01-04T22:36:12.027 回答
1

将结构翻转过来。让每个“页面”组件控制自己的布局。

制作一个布局更高阶的组件(接受一个组件类并返回一个组件类的函数):

function LayoutHOC({ title, theme, component: ContentComponent }) {
    return class LayoutWrapper extends React.Component {
        render() {
            return (
                <div>
                    <Header title={title} theme={theme} />
                    <Page title={title} theme={them}>
                        <ContentComponent {...this.props} />
                    </Page>
                </div>
            )
        }
    }
}

使文件夹结构域特定,如pages/about/MyAboutPage.jsx保存主要组件内容。

然后制作pages/about/index.js并导出包含在布局高阶组件中的内容组件。

index.js

import MyAboutPage from './MyAboutPage';
export default LayoutHOC({ title: 'my title', theme: 'alt', component: MyAboutPage })

然后在你的路线中你可以import About from './pages/about'(因为它使用 index.js 你不必担心嵌套的文件夹结构)。

缺点是您必须为每个域/路由创建一个 index.js。好处是您的内容组件不知道其布局,并且每个页面/路由都可以根据需要控制自己的页眉/页脚。

这个模式是从这个 React 样板项目中偷来的

于 2018-01-05T17:56:42.827 回答