如何以编程方式在材质UI中设置选项卡中的活动选项卡

时间:2017-08-31 10:04:37

标签: reactjs material-ui

我正在使用Material UI和React,我正在以编程方式创建多个标签,如下所示:

return (
    <div>
        <Tabs>
            {this.state.elements.map(elem => {
                return (
                    <Tab key={elem.elemID} label={elem.name} >
                        <div>
                           // rest removed for brevity
                        </div>
                    </Tab>
                )
            })}
        </Tabs>
    </div>
);

这样做,并显示选项卡,但问题是默认情况下,当组件呈现时,第一个选项卡是活动选项卡。然而,我想根据我从道具获得的id值以编程方式设置活动选项卡。所以基本上,如果this.props.selectedID === elem.elemID,那么我希望该组件在组件呈现时成为活动选项卡。当然,一旦呈现组件,用户应该可以自由地单击并在选项卡之间切换。知道如何实现吗?

5 个答案:

答案 0 :(得分:2)

使用valueTabs上的Tab道具使其成为受控制的组件:

<Tabs value={this.props.selectedID}>
    {this.state.elements.map(elem => {
            return (
                <Tab key={elem.elemID} label={elem.name} value={elem.elemID}>
                    <div>
                       // rest removed for brevity
                    </div>
                </Tab>
            )
        })}
</Tabs>

答案 1 :(得分:0)

TL DR; 假设您正在尝试将其映射到URL,这里的诀窍是以编程方式设置&#34;值&#34; <Tab>的属性到URL当前具有的属性。我假设您正在使用React Router

示例:

const baseUrls = ['', 'online-manga-reader', 'admin'];

class TabBar extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      value: this.processPathName(),
    };
  }

  processPathName(){
    const path = this.props.location.pathname.split('/')[1];
    const value =  baseUrls.indexOf(path);
    return value !== -1 ? value : 0; // This is the default one.
  }

  handleChange = (event, value) => {
    this.setState({ value });
    this.returnTabContainer(value);
  }

  returnTabContainer(value) {

    switch (value) {
      case 1:
        this.props.history.push('/online-manga-reader');
        break;
      case 2:
        this.props.history.push('/admin/article');
        break;
      default:
        this.props.history.push('/');
    }
  }

  returnTabAdmin() {
    return this.props.isAdmin ? <Tab label="Admin Tab" /> : '';
  }

  render() {
    const { classes } = this.props;
    const { value } = this.state;

    return (
      <div className={classes.root}>
        <AppBar position="static">
          <Tabs 
            value={value} 
            onChange={(evt, val) => {this.handleChange(evt, val); }}
          >
            <Tab label="Home" />
            <Tab label="Online Manga Reader" />
            {this.returnTabAdmin()}
          </Tabs>
          <LoginButton />
        </AppBar>
      </div>
    );
  }
}
export default connect(mapStateToProps)(withStyles(styles)(withRouter(TabBar)));

<强>解释

const baseUrls = ['', 'online-manga-reader', 'admin'];

这是一个位于类外部的数组,它包含URL的第一个路径(或基本URL):

这将匹配基本URL(因此将选择第一个) http://example.com/

这一个,第二个将匹配

第三个:   - http://example.com/admin   - http://example.com/admin/article/create

&#34;技巧&#34;我在这里使用的是processPathName()方法。 它从React-Router读取当前的URL,然后调用split,它已经在所需的部分中解析了你的URL:

http://example.com/admin/article/create 

将翻译为:

/ admin article create

始终将我们放回1我们正在寻找的位置(这是分割中的一个)。

有了这个,我们使用好的&#39; indexOf在数组内部搜索路径。如果找到它,它将返回与我们的标签位置匹配的数字。这就是为什么对他们来说同样重要的原因。

如果它没有找到它,我们设置一个默认值(在这种情况下,我们将其设置为零,这是主页的原因)。

您的商品应该正常呈现,没有任何问题。

答案 2 :(得分:0)

这是我作为带有钩子的最小通用示例的答案。我还假设您正在使用React Router。它实际上将url状态链接到Tab的“ selectedness”(在更改和呈现时):

const NavTabs = ({ history, location }) => {
  function getInitialTab() {
    switch (true) {
      case /\/componentone/.test(location.pathname):
        return 0
      case /\/componenttwo/.test(location.pathname):
        return 1
      default:
        return 0
    }
  }

  const [value, setValue] = useState(getInitialTab())

  function handleChange(event, val) {
    setValue(val)
    switch (val) {
      case 0:
        history.push('/componentone')
        break
      case 1:
        history.push('/componenttwo')
        break
      default:
        break
    }
  }

  return (
    <NoSsr>
      <div>
        <AppBar position="static">
          <Tabs
            variant="fullWidth"
            value={value}
            onChange={handleChange}
          >
            <Tab label="Component One" />
            <Tab label="Component Two" />
          </Tabs>
        </AppBar>
        {value === 0 && (
          <Typography component="div">
            <ComponentOne history={history} location={location} />
          </Typography>
        )}
        {value === 1 && (
          <Typography component="div">
            <ComponentTwo history={history} location={location} />
          </Typography>
        )}
      </div>
    </NoSsr>
  )
}

答案 3 :(得分:0)

Jose A的回答正确。使用React Material选项卡,您可以在初始化Tabs组件时使用“ useState”钩子来设置状态:

import requests
import psycopg2

conn_string = "host='xx' dbname='xx' user='xx' password='xx'"

def main():
    headers = {
        'authority': 'xx-api.xx.com',
        'origin': 'https://www.example.com',
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36',
        'accept': '*/*',
        'sec-fetch-site': 'same-site',
        'sec-fetch-mode': 'cors',
        'referer': 'https://example.com/xx-calendar',
        'accept-encoding': 'gzip, deflate, br',
        'accept-language': 'en-GB,en-US;q=0.9,en;q=0.8',

    }

    response = requests.get('https://example.com/en/api/v1/x/xxx', headers=headers)
    data = response.json()['data']


    fields = [
            'dateUtc',
            'countryCode',
            'name',
            'potency',
            'previous',
            'unit',
            'volatility'
    ]

    conn = psycopg2.connect(conn_string)
    cursor=conn.cursor()
    for item in data:
        my_data = [item[field] for field in fields]
        cursor.execute("INSERT INTO economic_calendar VALUES (%s, %s, %s,%s,%s,%s,%s,)", tuple(my_data))


if __name__ == '__main__':
    main()

React Material Tabs

答案 4 :(得分:0)

您可以使用状态来设置初始选项卡选择。

const [value, setValue] = React.useState(2);

  const handleChange = (event, newValue) => {
    setValue(newValue);
  };