在React项目中,我有一个组件Header.js
,它是全局布局的一部分,并且在每个页面上使用。路由是通过 React Router v4 完成的。
Header.js
组件应该有不同的子组件(例如面包屑或标题),具体取决于我当前所在的页面。
示例:在 HomePage.js
上,我想显示面包屑。但在 AboutPage.js
上,我只想有一个标题。
<App>
<Header />
<AnotherComponent />
<MoreComponents />
<BrowserRouter>
...
</BrowserRouter>
</App>
我考虑过将 Header.js
制作为 HOC,但由于布局和样式原因,我无法将其嵌入到每个页面中。它需要位于 App.js
中完全相同的位置。
有什么想法/技术吗?
编辑:理想情况下,我希望每个页面都有 Header.js
的内容,就像 Helmet 包所做的那样:
<>
{/* HomePage.js */}
<HeaderPortal>
<p>Content for the header</p>
</HeaderPortal>
<PageContent />
</>
最佳答案
实现此目的的一种方法是使用 React 的 context API,但是您必须在 DOM 中包装得相当高,以便能够从任何地方提供 header 内容的 setter 和 getter。
标题组件如下所示:
const HeaderContext = React.createContext();
// Provides the context and state - wrap app
export class HeaderProvider extends React.Component {
state = {};
render() {
const { children } = this.props;
return (
<HeaderContext.Provider
value={{
header: this.state.header,
setHeader: ({ header }) => this.setState({ header })
}}
>
{children}
</HeaderContext.Provider>
);
}
}
// Wrapper around WHERE the header will be rendered
export function HeaderPlacement() {
return (
<HeaderContext.Consumer>{({ header }) => header}</HeaderContext.Consumer>
);
}
// Wrapper for setting the header CONTENT
export function HeaderPortal({ children }) {
return (
<HeaderContext.Consumer>
{({ header, setHeader }) =>
!header // Guard against setting the header in an endless loop
&& setHeader({ header: children })}
</HeaderContext.Consumer>
);
}
然后用法将如下所示:
function App() {
return (
<HeaderProvider>
<div className="App">
<HeaderPlacement />
<Page />
</div>
</HeaderProvider>
);
}
function Page() {
return (
<React.Fragment>
<HeaderPortal><h1>Page A Test</h1></HeaderPortal>
<div>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. In ex odio,
eleifend in consequat nec, maximus lobortis ligula. Duis elementum, diam
et imperdiet pulvinar, nulla ligula commodo elit, ac ullamcorper justo
mauris quis velit.
</div>
</React.Fragment>
);
}
如果多个后代尝试设置 header 内容,您必须小心,因为您最终会遇到循环 setState
问题,或者一个会覆盖另一个。
这绝对不是唯一的方法,我避免使用钩子(Hook),但这肯定是 React-y 方法。
在此处查看代码和框:https://codesandbox.io/s/pj2q10700j
关于javascript - react : Change component's children from the outside,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54254273/