#javascript #reactjs #react-router #jsx
#javascript #reactjs #react-маршрутизатор #jsx
Вопрос:
Я создаю простое приложение react, используя React версии 16.7 и MDB (Material Design для начальной загрузки). react-router-dom
обрабатывает мою систему маршрутизации. Я хочу, чтобы моя панель навигации была прозрачной на главной странице, а на других страницах я хочу, чтобы она была темной. Мой код выглядит следующим образом:
App.js
class App extends Component {
state = {
collapseID: ""
}
toggleCollapse = collapseID => () =>
this.setState(prevState => ({
collapseID: prevState.collapseID !== collapseID ? collapseID : ""
}));
closeCollapse = collapseID => () =>
this.state.collapseID === collapseID amp;amp; this.setState({ collapseID: "" });
render() {
const overlay = (
<div
id="sidenav-overlay"
style={{ backgroundColor: "transparent" }}
onClick={this.toggleCollapse("mainNavbarCollapse")}
/>
);
const { collapseID } = this.state;
return (
<Router>
<div className="flyout">
<MDBNavbar color="elegant-color-dark" dark expand="md" fixed="top" scrolling transparent>
<MDBContainer>
<MDBNavbarBrand href="/">
<img src={Logo} height="50" alt="Logo" />
</MDBNavbarBrand>
<MDBNavbarToggler onClick={this.toggleCollapse("mainNavbarCollapse")} />
<MDBCollapse id="mainNavbarCollapse" isOpen={this.state.collapseID} navbar>
<MDBNavbarNav right>
<MDBNavItem>
<MDBNavLink exact to="/" onClick={this.closeCollapse("mainNavbarCollapse")} >
Home
</MDBNavLink>
</MDBNavItem>
<MDBNavItem>
<MDBNavLink onClick={this.closeCollapse("mainNavbarCollapse")} to="/about" >
About
</MDBNavLink>
</MDBNavItem>
<MDBNavItem>
<MDBNavLink onClick={this.closeCollapse("mainNavbarCollapse")} to="/products">
Products
</MDBNavLink>
</MDBNavItem>
<MDBNavItem>
<MDBNavLink onClick={this.closeCollapse("mainNavbarCollapse")} to="/trading">
Trading
</MDBNavLink>
</MDBNavItem>
<MDBNavItem>
<MDBNavLink onClick={this.closeCollapse("mainNavbarCollapse")} to="/contact">
Contact
</MDBNavLink>
</MDBNavItem>
</MDBNavbarNav>
</MDBCollapse>
</MDBContainer>
</MDBNavbar>
{collapseID amp;amp; overlay}
<main style={{ marginTop: "0" }}>
<Routes />
</main>
</div>
</Router>
);
}
}
export default App;
Routes.js
class Routes extends React.Component {
render() {
return (
<Switch>
<Route exact path="/" component={Home} />
<Route exact path="/about" component={About} />
<Route exact path="/products" component={Products} />
<Route exact path="/trading" component={Trading} />
<Route exact path="/contact" component={Contact} />
<Route
render = {function () {
return <h1 className="text-center m-5">Page Not Found</h1>;
}}
/>
</Switch>
);
}
}
export default Routes;
In App.js
, как вы можете видеть, <MDBNavbar color="elegant-color-dark" dark expand="md" fixed="top" scrolling transparent>
имеет атрибут transparent
. Я хочу, чтобы это было только на главной странице. На других страницах это будет выглядеть так: <MDBNavbar color="elegant-color-dark" dark expand="md" fixed="top" scrolling>
.
Я пытался использовать states
и props
, но безуспешно. Как я могу решить эту проблему?
Заранее спасибо.
Ответ №1:
Вы можете использовать withRouter
HOC из react-router ( https://github.com/ReactTraining/react-router/blob/master/packages/react-router/docs/api/withRouter.md ) для получения location
реквизитов в панели навигации, извлеченных как отдельный компонент. Это более или менее дало бы это (за вычетом реквизитов, отсутствующих на панели навигации):
const NavBar = ({location, collapseID, closeCollapse, toggleCollapse}) => <MDBNavbar color={location.pathname === "home"? "elegant-color-dark": ""} dark expand="md" fixed="top" scrolling transparent>
<MDBContainer>
<MDBNavbarBrand href="/">
<img src={Logo} height="50" alt="Logo" />
</MDBNavbarBrand>
<MDBNavbarToggler onClick={toggleCollapse("mainNavbarCollapse")} />
<MDBCollapse id="mainNavbarCollapse" isOpen={collapseID} navbar>
<MDBNavbarNav right>
<MDBNavItem>
<MDBNavLink exact to="/" onClick={closeCollapse("mainNavbarCollapse")} >
Home
</MDBNavLink>
</MDBNavItem>
<MDBNavItem>
<MDBNavLink onClick={closeCollapse("mainNavbarCollapse")} to="/about" >
About
</MDBNavLink>
</MDBNavItem>
<MDBNavItem>
<MDBNavLink onClick={closeCollapse("mainNavbarCollapse")} to="/products">
Products
</MDBNavLink>
</MDBNavItem>
<MDBNavItem>
<MDBNavLink onClick={closeCollapse("mainNavbarCollapse")} to="/trading">
Trading
</MDBNavLink>
</MDBNavItem>
<MDBNavItem>
<MDBNavLink onClick={closeCollapse("mainNavbarCollapse")} to="/contact">
Contact
</MDBNavLink>
</MDBNavItem>
</MDBNavbarNav>
</MDBCollapse>
</MDBContainer>
</MDBNavbar>
const NavBarWithRouter = withRouter(NavBar)
class App extends Component {
state = {
collapseID: ""
}
toggleCollapse = collapseID => () =>
this.setState(prevState => ({
collapseID: prevState.collapseID !== collapseID ? collapseID : ""
}));
closeCollapse = collapseID => () =>
this.state.collapseID === collapseID amp;amp; this.setState({ collapseID: "" });
render() {
const overlay = (
<div
id="sidenav-overlay"
style={{ backgroundColor: "transparent" }}
onClick={this.toggleCollapse("mainNavbarCollapse")}
/>
);
const { collapseID } = this.state;
return (
<Router>
<div className="flyout">
<NavBarWithRouter toggleCollapse={this. toggleCollapse} closeCollapse={this.closeCollapse} collapseID={collapseID} />
{collapseID amp;amp; overlay}
<main style={{ marginTop: "0" }}>
<Routes />
</main>
</div>
</Router>
);
}
}
export default App;
Комментарии:
1. Это работает, но панель навигации не может видеть
collapseID
иcloseCollapse()
2. Передайте их в качестве реквизитов в NavBarWithRouter
3. Можете ли вы показать мне, я новичок. Мне нужно
collapseID
,closeCollapse()
иoverlay
в моей панели навигации.4. Спасибо. Что мне делать, если я преобразовываю переменную navbar в компонент react (например Navbar.js )? Я думаю, что я должен получить реквизиты в конструкторе навигационной панели?
5. Не обязательно — посмотрите на мой код, у NavBar нет конструктора. У вас может быть функциональный компонент (обычная функция JS), где реквизитами являются аргументы функции: reactjs.org/docs/components-and-props.html
Ответ №2:
Вы можете использовать window.location.pathname
и сопоставить его с маршрутом домашней страницы, чтобы условно передавать реквизиты.
Определите объект props, который вы хотите передать, предпочтительно в componentDidMount
App.js
:
let homePageProps = {};
if (window.location.pathname === "/") {
homePageProps.transparent = "transparent";
}
Затем распространите его.
<MDBNavbar color="elegant-color-dark" dark expand="md" fixed="top" scrolling {...homePageProps}>
Комментарии:
1. Это не сработало. Если я определяю
homePageProps
внутриcomponentDidMount
, возникает другая ошибка: неопределенная переменная. Если определить его снаружи, он не работает.2. Какая переменная не определена?
3. @JibinJoseph,
homePageProps
4. Вам не кажется, что это действительно забавная ошибка? Даже если вы объявите это в
componentDidMount
, это должно сработать.5. Да, конечно. Я смог использовать его с
this
ключевым словом, но когда я перехожу на другую страницу, панель навигации остается прежней. DOM не был обновлен.