0

我有一个反应组件,它使用material-ui tabsand react-swipeable-views。我遇到的问题是,切换选项卡时,显示的 url 没有改变,我注意到这是 react-swipeable-views 逻辑。我也想申请react-router以更改选项卡上的 url,同时保留 react-swipeable-view 逻辑。

以下是我的代码的一部分,其中包含一些其他详细信息:

import SwipeableViews from 'react-swipeable-views';
import Tabs from '@material-ui/core/Tabs';
import Tab from '@material-ui/core/Tab';

export default function TasksViewTabs(props) {
        const task = props.match.params.taskid
        const classes = useStyles();
        const [value, setValue] = React.useState(0);
    
        const handleChange = (event, newValue) => {
            console.log('new value', newValue)
            setValue(newValue);
        };
    
        const handleChangeIndex = (index) => {
            setValue(index);
        };
    
        console.log('value', value)
    
        return (
            <>
                    <Tabs value={value} onChange={handleChange} classes={{indicator: classes.indicator}}>
                        <Tab className={value === 0? classes.active_tabStyle : null} label="Runs" {...a11yProps(0)} />
                        <Tab className={value === 1? classes.active_tabStyle : null} label="Tasks" {...a11yProps(1)} />
                        <Tab className={value === 2? classes.active_tabStyle : null} label="Settings" {...a11yProps(2)} />
                    </Tabs>
                <SwipeableViews index={value} onChangeIndex={handleChangeIndex}>
                        <RunApp value={value} index={0} taskid={task} />
                        <TaskApp value={value} index={1} taskid={task} />
                        <SettingsApp value={value} index={2} taskid={task} />
                </SwipeableViews>
            </>
        );
    }

默认的 url 显示如下所示,更改视图时它不会更改:localhost:3000/clusters/<task:id> 但是我有三个选项卡 ( runs, tasks, settings),它们控制 react-swipeable-views。我希望 url在选项卡更改时分别显示为 ( localhost:3000/clusters/<task:id>/runs, localhost:3000/clusters/<task:id>/tasks, ) 。localhost:3000/clusters/<task:id>/settings

我怎样才能做到这一点并保留反应可滑动的逻辑?

谢谢

以防万一,该 url 是从包含表格的组件的 history.push 加载的。仅在单击表格行时。

  rowClicked = (params) => {
    return (
      history.push({
        pathname: `/clusters/${params.data.md5_hash}`
      })
    )
  }

谢谢,我希望这会有所帮助:)

4

2 回答 2

1

经过一番研究,我找到了答案。对路由更改做出反应的可滑动库的最佳库是react-swipeable-routes,所以我从 react-swipeable-views 更改为这个并应用了反应路由的使用,它就像一个魅力。

//import SwipeableViews from 'react-swipeable-views'; //don't use this
import SwipeableRoutes from "react-swipeable-routes"; //use this
import Tabs from '@material-ui/core/Tabs';
import Tab from '@material-ui/core/Tab';
export default function FullWidthTabs(props) {
    const task = props.match.params.taskid
    // const theme = useTheme();
    const classes = useStyles();
    const [value, setValue] = React.useState(0);

    const handleChange = (event, newValue) => {
        console.log('new value', newValue)
        setValue(newValue);
    };

    const handleChangeIndex = (index) => {
        setValue(index);
    };

    console.log('value', value)

    return (
        <>
            <HeaderContent>
                <Breadcrumbs />
                <ProfileMenu/>
            </HeaderContent>
            <Router> //use react-router
            <ToolBarContent>
//add routes in tabs
                <Tabs value={value} onChange={handleChange} classes={{indicator: classes.indicator}} style={{display: 'flex', justifyContent: 'space-between'}}>
                    <Tab to= {`clusters/${task}/runs`} className={value === 0? classes.active_tabStyle : null} label="Runs" {...a11yProps(0)}/>
                    <Tab to= {`clusters/${task}/tasks`} className={value === 1? classes.active_tabStyle : null} label="Tasks" {...a11yProps(1)}/>
                    <Tab to= {`clusters/${task}/settings`} className={value === 2? classes.active_tabStyle : null} label="Settings" {...a11yProps(2)}/>
                </Tabs>
            </ToolBarContent>
//the magic happens here
            <SwipeableRoutes  index={value} onChangeIndex={handleChangeIndex}>
            <Route path={`clusters/${task}/runs`} component={() => <RunApp value={value} index={0} taskid={task} />}/>
            <Route path={`clusters/${task}/tasks`} component={() => <TaskApp value={value} index={0} taskid={task} />}/>
            <Route path={`clusters/${task}/settings`} component={() => <SettingsApp value={value} index={0} taskid={task} />}/>
          </SwipeableRoutes>
          </Router>
        </>
    );
}
于 2020-11-03T12:36:42.843 回答
0

假设您有一个Route匹配路径“/clusters/:taskId”

<Route path="/clusters/:taskId" component={TasksViewTabs} />

那么这个路由可以匹配任何以“/clusters/:taskId”为前缀的路由,即

  • “/clusters/:taskId/运行”
  • “/clusters/:taskId/tasks”
  • “/clusters/:taskId/设置”

您可以更新您handleChangeIndex的也可以在索引更改时强制导航到匹配的子路由。

创建选项卡/路由配置

const tabConfig = [
  {
    component: RunApp,
    label: 'Runs',
    link: 'runs',
  },
  {
    component: TaskApp,
    label: 'Tasks',
    link: 'tasks',
  },
  {
    component: SettingsApp,
    label: 'Settings',
    link: 'settings',
  },
];

更新渲染以映射tabConfig到选项卡

return (
  <>
    <Tabs
      value={value}
      onChange={handleChange}
      classes={{ indicator: classes.indicator }}
    >
      {tabConfig.map(({ label }, i) => (
        <Tab
          key={i}
          className={value === i ? classes.active_tabStyle : null}
          label={label}
          { ...a11yProps(i) }
        />
      ))}
    </Tabs>
    <SwipeableViews
      index={value}
      onChangeIndex={handleChangeIndex}
    >
      {tabConfig.map(({ component: Component}, i) => (
        <Component key={i} value={value} index={i} taskid={task} />
      ))}
    </SwipeableViews>
  </>
);

更新handleChangeIndex以进行一些导航。

const { history, match } = props;
const { params: { taskid: task } } = match;

...

const handleChangeIndex = (index) => {
  setValue(index);
  history.replace(`/clusters/:taskId/${tabConfig[index].link}`);
};
于 2020-11-03T08:07:26.540 回答