재료-UI의 탭과 반응 라우터 4의 통합?
새로운 리액터-라우터 구문에서는Link
이동 경로에 대한 구성 요소. 하 지만 material-ui
?
내 경우에는 탭들을 주요 항법 시스템으로 사용하고 있어 이론상으로는 다음과 같은 것을 가져야 한다.
const TabLink = ({ onClick, href, isActive, label }) =>
<Tab
label={label}
onActive={onClick}
/>
export default class NavBar extends React.Component {
render () {
return (
<Tabs>
<Link to="/">{params => <TabLink label="Home" {...params}/>}</Link>
<Link to="/shop">{params => <TabLink label="shop" {...params}/>}</Link>
<Link to="/gallery">{params => <TabLink label="gallery" {...params}/>}</Link>
</Tabs>
)
}
}
그러나 그것이 렌더링되면 물질적 의리는 그 아이의 실수를 던진다.Tabs
a임에 틀림없다.Tab
하면 좋을까어떻게 진행하면 좋을까? ?isActive
턱받이?
미리 고맙다.
또 다른 솔루션(컨트롤러나 HOC가 없는 https://codesandbox.io/s/l4yo482pll), 순수한 반응 방식 및 물질-UI 구성 요소:
import React, { Fragment } from "react";
import ReactDOM from "react-dom";
import Tabs from "@material-ui/core/Tabs";
import Tab from "@material-ui/core/Tab";
import { Switch, Route, Link, BrowserRouter, Redirect } from "react-router-dom";
function App() {
const allTabs = ['/', '/tab2', '/tab3'];
return (
<BrowserRouter>
<div className="App">
<Route
path="/"
render={({ location }) => (
<Fragment>
<Tabs value={location.pathname}>
<Tab label="Item One" value="/" component={Link} to={allTabs[0]} />
<Tab label="Item Two" value="/tab2" component={Link} to={allTabs[1]} />
<Tab
value="/tab3"
label="Item Three"
component={Link}
to={allTabs[2]}
/>
</Tabs>
<Switch>
<Route path={allTabs[1]} render={() => <div>Tab 2</div>} />
<Route path={allTabs[2]} render={() => <div>Tab 3</div>} />
<Route path={allTabs[0]} render={() => <div>Tab 1</div>} />
</Switch>
</Fragment>
)}
/>
</div>
</BrowserRouter>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
강사가 다음과 같은 기록 방법을 사용할 수 있도록 Router 4.0과 함께 Router를 사용하여 탭 구성 요소를 포장하는 데 도움을 주셨습니다.
import React, {Component} from "react";
import {Tabs, Tab} from 'material-ui';
import { withRouter } from "react-router-dom";
import Home from "./Home";
import Portfolio from "./Portfolio";
class NavTabs extends Component {
handleCallToRouter = (value) => {
this.props.history.push(value);
}
render () {
return (
<Tabs
value={this.props.history.location.pathname}
onChange={this.handleCallToRouter}
>
<Tab
label="Home"
value="/"
>
<div>
<Home />
</div>
</Tab>
<Tab
label="Portfolio"
value="/portfolio"
>
<div>
<Portfolio />
</div>
</Tab>
</Tabs>
)
}
}
export default withRouter(NavTabs)
index.js에 BrowserRouter를 추가하기만 하면 바로 사용할 수 있다.
물질적 의에서 보고 있는 오류는 그것이 물질적 의를 가질 것을 기대하기 때문이다.<Tab>
의 직계 아들로 제공된 구성요소<Tabs>
구성 요소
가 찾은 , 쟈, 여기 가, 은 방 이이다.<Tabs>
스타일을 변경하지 않고 구성 요소:
import React, {Component} from 'react';
import {Tabs, Tab} from 'material-ui/Tabs';
import {Link} from 'react-router-dom';
export default class MyComponent extends Component {
render() {
const {location} = this.props;
const {pathname} = location;
return (
<Tabs value={pathname}>
<Tab label="First tab" containerElement={<Link to="/my-firs-tab-view" />} value="/my-firs-tab-view">
{/* insert your component to be rendered inside the tab here */}
</Tab>
<Tab label="Second tab" containerElement={<Link to="/my-second-tab-view" />} value="/my-second-tab-view">
{/* insert your component to be rendered inside the tab here */}
</Tab>
</Tabs>
);
}
}
속성을 '능동적' 을 하면 value
의 <Tabs>
도 있고, ㅇㅇㅇ이 해.value
각 탭의 속성, 즉 두 속성이 일치할 때 해당 탭에 활성 스타일을 적용한다.
Material 1.0의 베타 버전을 사용하고 브라우저 Back/Forward를 혼합물에 추가하는 다른 솔루션:
import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from 'material-ui/styles';
import AppBar from 'material-ui/AppBar';
import Tabs, { Tab } from 'material-ui/Tabs';
import { withRouter } from "react-router-dom";
import Home from "./Home";
import Portfolio from "./Portfolio";
function TabContainer(props) {
return <div style={{ padding: 20 }}>{props.children}</div>;
}
const styles = theme => ({
root: {
flexGrow: 1,
width: '100%',
marginTop: theme.spacing.unit * 3,
backgroundColor: theme.palette.background.paper,
},
});
class NavTabs extends React.Component {
state = {
value: "/",
};
componentDidMount() {
window.onpopstate = ()=> {
this.setState({
value: this.props.history.location.pathname
});
}
}
handleChange = (event, value) => {
this.setState({ value });
this.props.history.push(value);
};
render() {
const { classes } = this.props;
const { value } = this.state;
return (
<div className={classes.root}>
<AppBar position="static" color="default">
<Tabs
value={value}
onChange={this.handleChange}
scrollable
scrollButtons="on"
indicatorColor="primary"
textColor="primary"
>
<Tab label="Home" value = "/" />
<Tab label="Portfolio" value = "/portfolio"/>
</Tabs>
</AppBar>
{value === "/" && <TabContainer>{<Home />}</TabContainer>}
{value === "/portfolio" && <TabContainer>{<Portfolio />}</TabContainer>}
</div>
);
}
}
NavTabs.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withRouter(withStyles(styles)(NavTabs));
Tab 강조 표시가 있는 솔루션, Typecript 기반 및 react-route v5와 함께 작동:
설명:<Tab/>
여기에서는 반응 라우터의 링크로서 작업한다.의 값:<Tab/> to={'/all-event'}
그리고value={'/all-event'}
highlgihthighlighthighlighthdo가 같a아 한국이기 .
import { Container, makeStyles, Tab, Tabs } from '@material-ui/core';
import React from 'react';
import {
Link,
Route,
Switch,
useLocation,
Redirect,
} from 'react-router-dom';
import AllEvents from './components/AllEvents';
import UserEventsDataTable from './components/UserEventsDataTable';
const useStyles = makeStyles(() => ({
container: {
display: 'flex',
justifyContent: 'center',
},
}));
function App() {
const classes = useStyles();
const location = useLocation();
return (
<>
<Container className={classes.container}>
<Tabs value={location.pathname}>
<Tab
label='All Event'
component={Link}
to={`/all-event`}
value={`/all-event`}
/>
<Tab
label='User Event'
component={Link}
to={`/user-event`}
value={`/user-event`}
/>
</Tabs>
</Container>
<Switch>
<Route path={`/all-event`}>
<AllEvents />
</Route>
<Route path={`/user-event`}>
<UserEventsDataTable />
</Route>
<Route path={`/`}>
<Redirect from='/' to='/all-event' />
</Route>
</Switch>
</>
);
}
export default App;
사용할 수 있다browserHistory
리액트 로터 대신Link
구성 요소
import { browserHistory } from 'react-router'
// Go to /some/path.
onClick(label) {
browserHistory.push('/${label}');
}
// Example for Go back
//browserHistory.goBack()
<Tabs>
<Tab
label={label}
onActive={() => onClick(label)}
/>
</Tabs>
보다시피 간단히 할 수 있다.push()
당신의 목표물browserHistory
@gkatchmar가 말하듯이 당신은 사용할 수 있다.withRouter
고차 구성 요소, 그러나 사용 가능context API
. @gkatchmar가 Router와 함께 이미 보여줬기 때문에 나는 단지 보여줄 것이다.context API
이것은 실험적인 API라는 것을 명심해라.
https://stackoverflow.com/a/42716055/3850405
import React, {Component} from "react";
import {Tabs, Tab} from 'material-ui';
import * as PropTypes from "prop-types";
export class NavTabs extends Component {
constructor(props) {
super(props);
}
static contextTypes = {
router: PropTypes.object
}
handleChange = (event: any , value: any) => {
this.context.router.history.push(value);
};
render () {
return (
<Tabs
value={this.context.router.history.location.pathname}
onChange={this.handleChange}
>
<Tab
label="Home"
value="/"
>
<div>
<Home />
</div>
</Tab>
<Tab
label="Portfolio"
value="/portfolio"
>
<div>
<Portfolio />
</div>
</Tab>
</Tabs>
)
}
}
<BrowserRouter>
<div className={classes.root}>
<AppBar position="static" color="default">
<Tabs
value={this.state.value}
onChange={this.handleChange}
indicatorColor="primary"
textColor="primary"
fullWidth
>
<Tab label="Item One" component={Link} to="/one" />
<Tab label="Item Two" component={Link} to="/two" />
</Tabs>
</AppBar>
<Switch>
<Route path="/one" component={PageShell(ItemOne)} />
<Route path="/two" component={PageShell(ItemTwo)} />
</Switch>
</div>
다음 기능을 사용하는 간단한 해결 방법useLocation
훅. 주(州)가 필요 없다.그래도 라우터 v5를 반응시키십시오.
import { Tab, Tabs } from '@material-ui/core';
import { matchPath, NavLink, useLocation } from 'react-router-dom';
const navItems = [
{
id: 'one',
path: '/one',
text: 'One',
},
{
id: 'two',
path: '/two',
text: 'Two',
},
{
id: 'three',
path: '/three',
text: 'Three',
},
];
export default function Navigation() {
const { pathname } = useLocation();
const activeItem = navItems.find((item) => !!matchPath(pathname, { path: item.path }));
return (
<Tabs value={activeItem?.id}>
{navItems.map((item) => (
<Tab key={item.id} value={item.id} label={item.text} component={NavLink} to={item.path} />
))}
</Tabs>
);
}
나는 탭을 제어하고 위치 URL에서 포착되는 기본값을 생성하기 위해 이 후크를 만들었다.
const useTabValue = (array, mainPath = "/") => {
const history = useHistory();
const { pathname } = useLocation();
const [value, setValue] = useState(0);
const pathArray = pathname.split("/");
function handleChange(_, nextEvent) {
setValue(nextEvent);
history.push(`${mainPath}/${array[nextEvent]}`);
}
const findDefaultValue = useCallback(() => {
return array.forEach((el) => {
if (pathArray.indexOf(el) > 0) {
setValue(array.indexOf(el));
return;
}
});
}, [pathArray, array]);
useEffect(() => {
findDefaultValue();
}, [findDefaultValue]);
return {
handleChange,
value,
};
};
그리고 나는 이것을 이렇게 사용했다.
const NavigationBar = () => {
const classes = useStyles();
const allTabs = useMemo(() => ["home", "search"]);
const { handleChange, value } = useTabValue(allTabs, "/dashboard");
return (
<div className={classes.navBarContainer}>
<Tabs
centered
value={value}
variant="fullWidth"
onChange={handleChange}
className={classes.navBar}
>
<Tab color="textPrimary" icon={<HomeIcon />} />
<Tab color="textPrimary" icon={<ExploreIcon />} />
</Tabs>
</div>
);
};
나는 이것을 훨씬 더 쉽게 풀었다.(이것이 너무 잘작동해서 놀랐어.내가 미처 발견하지 못한 문제가 있을지도 몰라.)라우터 6과 리액션 17을 사용하고 있다(이 패키지가 더 최신인 것으로 알고 있다).어쨌든, 나는 handleChange 함수의 useNavigate 후크를 사용했을 뿐이다.따라서 이제는 스위치의 필요성이 없어지고 코드는 훨씬 단순해진다.아래를 참조하십시오.
let navigate = useNavigate();
const [selection, setSelection] = useState();
const handleChange = (event, newValue) => {
setSelection(newValue);
navigate(`${newValue}`);
}
return (
<Tabs value={selection} onChange={handleChange}>
<Tab label="Products" value="products" />
<Tab label="Customers" value="customers" />
<Tab label="Invoices" value="invoices" />
</Tabs>
);
}
handleChange 기능은 탭의 표시를 제어하고 올바른 경로로 이동하는 'handleChange' 기능을 업데이트한다. 구성요소를 Resact 공간의 어딘가로 설정하고 :style 경로를 올바르게 설정하면(Raction Router: https://reactrouter.com/docs/en/v6/getting-started/overview),에서 설명한 대로 pa의 어느 영역을 제어할 수도 있다.ge는 내용을 제공할 것이다.그게 누군가에게 도움이 되길 바래!
내 앱에서 이런 식으로 작동하게 만들었어.
import React, {useEffect, useRef} from 'react';
import PropTypes from 'prop-types';
import {makeStyles} from '@material-ui/core/styles';
import AppBar from '@material-ui/core/AppBar';
import Tabs from '@material-ui/core/Tabs';
import Tab from '@material-ui/core/Tab';
import Typography from '@material-ui/core/Typography';
import Box from '@material-ui/core/Box';
import Container from "@material-ui/core/Container";
import {Link} from "react-router-dom";
import MenuIcon from "@material-ui/icons/Menu";
import VideoCallIcon from "@material-ui/icons/VideoCall";
const docStyles = makeStyles(theme => ({
root: {
display: 'flex',
'& > * + *': {
marginLeft: theme.spacing(2),
},
},
appBarRoot: {
flexGrow: 1,
},
headline: {
marginTop: theme.spacing(2),
},
bodyCopy: {
marginTop: theme.spacing(1),
fontSize: '1.2rem',
},
tabContents: {
margin: theme.spacing(3),
},
}));
function TabPanel(props) {
const {children, value, index, classes, ...other} = props;
return (
<div
role="tabpanel"
hidden={value !== index}
id={`simple-tabpanel-${index}`}
aria-labelledby={`simple-tab-${index}`}
{...other}
>
{value === index && (
<Container>
<Box className={classes.tabContents}>
{children}
</Box>
</Container>
)}
</div>
);
}
function a11yProps(index) {
return {
id: `simple-tab-${index}`,
'aria-controls': `simple-tabpanel-${index}`,
};
}
function TabOneContents(props) {
const {classes} = props;
return (
<>
<Typography variant="h4" component={'h1'} className={classes.headline}>
Headline 1
</Typography>
<Typography variant="body1" className={classes.bodyCopy}>
Body Copy 1
</Typography>
</>
)
}
function TabTwoContents(props) {
const {classes} = props;
const nurseOnboardingPath = '/navigator/onboarding/' + Meteor.userId() + '/1';
return (
<>
<Typography variant="h4" component={'h1'} className={classes.headline}>
Headline 2
</Typography>
<Typography variant="body1" className={classes.bodyCopy}>
Body Copy 2
</Typography>
</>
)
}
export default function MUITabPlusReactRouterDemo(props) {
const {history, match} = props;
const propsForDynamicClasses = {};
const classes = docStyles(propsForDynamicClasses);
const [value, setValue] = React.useState(history.location.pathname.includes('/tab_2') ? 1 : 0);
const handleChange = (event, newValue) => {
setValue(newValue);
const pathName = '/' + (value == 0 ? 'tab_1' : 'tab_2');
history.push(pathName);
};
return (
<div className={classes.appBarRoot}>
<AppBar position="static" color="transparent">
<Tabs value={value} onChange={handleChange} aria-label="How It Works" textColor="primary">
<Tab label="Tab 1" {...a11yProps(0)} />
<Tab label="Tab 2" {...a11yProps(1)} />
</Tabs>
</AppBar>
<TabPanel value={value} index={0} classes={classes}>
<TabOneContents classes={classes}/>
</TabPanel>
<TabPanel value={value} index={1} classes={classes}>
<TabTwoContents classes={classes}/>
</TabPanel>
</div>
);
}
...및 Ract Router:
[.....]
<Route exact path="/tab_1"
render={(routeProps) =>
<MUITabPlusReactRouterDemo history={routeProps.history}
/>
}/>
<Route exact path="/tab_2"
render={(routeProps) =>
<MUITabPlusReactRouterDemo history={routeProps.history} />
}/>
[.....]
import React, { useContext, useEffect } from "react";
import PropTypes from "prop-types";
import Drawer from "@material-ui/core/Drawer";
import IconButton from "@material-ui/core/IconButton";
import MenuIcon from "@material-ui/icons/Menu";
import Typography from "@material-ui/core/Typography";
import useStyles from "./Styles";
import Tabs from "@material-ui/core/Tabs";
import Tab from "@material-ui/core/Tab";
import Box from "@material-ui/core/Box";
import { __t } from "core/translation/translation";
import BrowserData from "core/helper/BrowserData";
import profileMenuItems from "./MenuItems";
import LayoutContext from "components/layout/core/LayoutContext";
import { useHistory, useParams } from "react-router-dom";
function TabPanel(props) {
const { children, value, index, ...other } = props;
return (
<div
role="tabpanel"
hidden={value !== index}
id={`vertical-tabpanel-${index}`}
aria-labelledby={`vertical-tab-${index}`}
{...other}
>
{value === index && (
<Box p={3}>
<Typography>{children}</Typography>
</Box>
)}
</div>
);
}
TabPanel.propTypes = {
children: PropTypes.node,
index: PropTypes.any.isRequired,
value: PropTypes.any.isRequired,
};
export default function UserProfile(props) {
const { window } = props;
const classes = useStyles();
const history = useHistory();
const { page } = useParams();
const { isDesktop } = useContext(LayoutContext);
const [open, setOpen] = React.useState(false);
const [value, setValue] = React.useState(0);
const handleChange = (event, newValue) => {
setValue(newValue);
history.push("/yourPath/" + newValue);
};
useEffect(() => {
if (!!page) {
setValue(eval(page));
}
}, [page]);
const getContent = () => {
const { component: Component } = MenuItems[value];
return <Component />;
};
const handleDrawerToggle = () => {
setOpen((prevState) => !prevState);
};
const Menu = (
<div>
<Tabs
orientation="vertical"
variant="scrollable"
value={value}
onChange={handleChange}
className={classes.tabs}
>
{MenuItems.map(
({ label, iconPath, iconClassName = "" }, index) => (
<Tab
label={label}
id={`vertical-tab-${index}`}
aria-controls={`vertical-tabpanel-${index}`}
className={classes.tab}
icon={
<img className={iconClassName} src={iconPath} alt={label} />
}
/>
)
)}
</Tabs>
</div>
);
return (
<div className={classes.root}>
<IconButton
color="inherit"
aria-label="open drawer"
edge="start"
onClick={handleDrawerToggle}
className={classes.drawerToggleButton}
>
<MenuIcon />
</IconButton>
<nav className={classes.drawer}>
<Drawer
anchor="left"
open={isDesktop ? true : open}
onClose={handleDrawerToggle}
variant={isDesktop ? "permanent" : "temporary"}
classes={{
paper: classes.drawerPaper,
}}
ModalProps={{
keepMounted: true,
}}
>
{Menu}
</Drawer>
</nav>
<main className={classes.content}>
<TabPanel
value={value}
key={value}
index={value}
className={classes.tabPanel}
>
{getContent()}
</TabPanel>
</main>
</div>
);
}
참조URL: https://stackoverflow.com/questions/41638688/material-uis-tabs-integration-with-react-router-4
'programing' 카테고리의 다른 글
PropTypes DOM 요소를 반응하시겠습니까? (0) | 2022.03.14 |
---|---|
Vue.js—v-model과 v-bind의 차이 (0) | 2022.03.14 |
어레이 속성을 중단하지 않고 TypeScript 딥 부분 매핑 유형을 구현하는 방법 (0) | 2022.03.14 |
ASP에서 VueJS에 의한 경로 처리 방법.엔드포인트를 사용하는 NET Core? (0) | 2022.03.14 |
Python 3에서 웹에서 파일 다운로드 (0) | 2022.03.14 |