V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
lolizeppelin
V2EX  ›  程序员

初学 react 的新手求助

  •  
  •   lolizeppelin · 2018-03-15 15:01:39 +08:00 · 2244 次点击
    这是一个创建于 2446 天前的主题,其中的信息可能已经有所发展或是发生改变。

    学习 react 和 material ui 过程中遇到的几个 js 问题想请教,下面是代码

    import React, {Component} from 'react';
    import AppBar from 'material-ui/AppBar';
    import IconButton from 'material-ui/IconButton';
    import IconMenu from 'material-ui/IconMenu';
    import MenuItem from 'material-ui/MenuItem';
    import FlatButton from 'material-ui/FlatButton';
    import ActionList from 'material-ui/svg-icons/action/list';
    import ActionAccount from 'material-ui/svg-icons/action/account-box';
    import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'
    
    import Drawer from 'material-ui/Drawer';
    import ArrowDropRight from 'material-ui/svg-icons/navigation-arrow-drop-right';
    
    
    class MyDrawer extends Component {
    
        menu = "empty";
    
        isOpen(status) {
    
            return (status === this.menu)
    
        };
    
    
    }
    
    
    class AccountDrawer extends MyDrawer {
    
        menu = "account";
    
        render() {
            return (
                <Drawer open={this.isOpen(this.props.status)}>
                    <AppBar title="账号管理"
                            showMenuIconButton={false}
                            onTitleClick={this.props.close}/>
                    <MenuItem>角色列表</MenuItem>
                    <MenuItem>用户列表</MenuItem>
                </Drawer>
            );
        }
    }
    
    
    
    class GlobalDrawer extends MyDrawer {
    
        menu = "global";
    
        render() {
            return (
                <Drawer open={this.isOpen(this.props.status)}>
                    <AppBar title="全局服务"
                            showMenuIconButton={false}
                            onTitleClick={this.props.close}/>
                    <MenuItem>服务器列表</MenuItem>
                    <MenuItem>数据库列表</MenuItem>
                </Drawer>
            );
        }
    }
    
    
    
    
    
    class MyApp extends Component {
    
        constructor() {
            super();
            this.state = {
                logged: false,
                drawer: "close"
            };
        }
    
    
        login = (event) => {
            if (this.state.logged) {
                this.setState({logged: false, drawer: "close"});
            }
            else {
                this.setState({logged: true});
            }
        };
    
    
        openDrawer = (drawer, event) => {
            this.setState({drawer: drawer});
        };
    
        closeDrawer = (event) => {
            this.setState({drawer: "close"});
        };
    
    
    
        render() {
            return (
                <MuiThemeProvider>
                    <AppBar title="后台管理系统"
                            iconElementLeft={
                                <IconMenu {...this.props}
                                          iconButtonElement={<IconButton><ActionList /></IconButton>}
                                          targetOrigin={{horizontal: 'left', vertical: 'top'}}
                                          anchorOrigin={{horizontal: 'left', vertical: 'top'}}>
                                    <MenuItem primaryText="账号管理" onClick={this.openDrawer.bind(this, "account")}/>
                                    <MenuItem primaryText="全局服务" onClick={this.openDrawer.bind(this, "global")}/>
                                    <MenuItem primaryText="游戏管理"
                                              rightIcon={<ArrowDropRight />}
                                              menuItems={[
                                                  <MenuItem primaryText="游戏 A"
                                                            onClick={this.openDrawer.bind(this, "gameA")}/>,
                                                  <MenuItem primaryText="游戏 B"
                                                            onClick={this.openDrawer.bind(this, "gameB")}/>,
                                                  <MenuItem primaryText="游戏 C"
                                                            onClick={this.openDrawer.bind(this, "gameC")}/>,
                                              ]}
                                    />
                                    <MenuItem primaryText="运营管理"
                                              rightIcon={<ArrowDropRight />}
                                              menuItems={[
                                                  <MenuItem primaryText="全局"
                                                            onClick={this.openDrawer.bind(this, "yunyinGlobal")}/>,
                                                  <MenuItem primaryText="游戏 A"
                                                            onClick={this.openDrawer.bind(this, "yunyinGgameA")}/>,
                                                  <MenuItem primaryText="游戏 B"
                                                            onClick={this.openDrawer.bind(this, "yunyinGgameB")}/>,
                                                  <MenuItem primaryText="游戏 C"
                                                            onClick={this.openDrawer.bind(this, "yunyinGgameC")}/>,
                                              ]}
                                    />
                                </IconMenu>}
                            iconElementRight={this.state.logged ?
                                <IconMenu {...this.props}
                                          iconButtonElement={
                                              <IconButton tooltip="账户">
                                                  <ActionAccount />
                                              </IconButton>}
                                          targetOrigin={{horizontal: 'right', vertical: 'top'}}
                                          anchorOrigin={{horizontal: 'right', vertical: 'top'}}>
                                    <MenuItem primaryText="刷新" />
                                    <MenuItem primaryText="帮助" />
                                    <MenuItem primaryText="登出"
                                              onClick={this.login}/>
                                </IconMenu> :
                                <FlatButton {...this.props} label="登陆"
                                            onClick={this.login}
                                />}
                            onTitleClick={this.closeDrawer}
    
                    />
                    <AccountDrawer status={this.state.drawer} close={this.closeDrawer}/>
                    <GlobalDrawer status={this.state.drawer} close={this.closeDrawer}/>
                </MuiThemeProvider>
    
            );
        }
    }
    
    
    export default MyApp;
    

    问题一 python 里类可以直接访问到类属性,这样就可以通过 AccountDrawer.menu 获取到对应字符串 JS 里不行,意味着我就要把所有的相关 menu 名字定义到外面的常量里?然后 class 和外部都等于这个常量? 大一点的工程里都是这样做的?

    问题二 AppBar 中 iconElementLeft 里的 IconMenu 可以不可以请求外部 json 获取列表生成,我试了半天没试出可实现的语法 0 0

    问题三 Drawer 的实现方法是否是合理的

    10 条回复    2018-03-15 20:03:16 +08:00
    lolizeppelin
        1
    lolizeppelin  
    OP
       2018-03-15 15:03:15 +08:00
    还有个问题, 我现在的 Drawer 也是一个一个加在代码阿里的....有啥写法能让 jsx 的行驶是动态的?
    fds
        2
    fds  
       2018-03-15 15:44:58 +08:00
    1、类的属性可以通过 static get menu() { return “ empty ”; } 。
    2、fetch 应该写在 store 的逻辑里,这里只是展示层,把数据显示出来。数据的获取你可以考虑在 MyApp 的某一个回调里激活。
    3、MyDrawer AccountDrawer GlobalDrawer 实际上可以统一成一个,然后用的时候
    ``` <MyDrawer title="账号管理" menuItems={["角色列表","用户列表"]} status=... close=... /> ``` 这样
    lolizeppelin
        3
    lolizeppelin  
    OP
       2018-03-15 16:23:41 +08:00
    ```javascript
    const topMemus = {
    text : '后台管理系统',
    right: {
    login: {
    text: '账户',
    login: {
    text: '登陆'
    },
    loginout: {
    text: '登出'
    },
    flush: {
    text: '刷新'
    },
    help: {
    text: '帮助'
    },
    }
    },

    global: {
    text: '全局服务',
    key: 'global'
    },

    game: {
    text: '游戏管理', kye: 'GAMES',
    },

    games: [
    {text: '游戏 A', key: 'gameA'},
    {text: '游戏 B', key: 'gameB'},
    {text: '游戏 C', key: 'gameC'},
    ],

    operate: {
    text: '运营管理', kye: 'OPERATE',
    },

    operates: [
    {text: '全局数据', key: 'opGameA'},
    {text: '游戏 A', key: 'opGameA'},
    {text: '游戏 B', key: 'opGameB'},
    {text: '游戏 C', key: 'opGameC'},
    ],


    account: {
    text: '账号管理',
    key: 'account'
    }
    };

    menuItems={
    topMemus.operates.map((operate)=> (
    <MenuItem primaryText={operate.text}
    onClick={this.openDrawer.bind(this, operate.key)}/>
    ))

    ```
    我用了个 obj 来测试可以动态生成,虽然现在还是有,但是好歹可以了
    Drawer 应该也可以用类似方式
    Debiancc
        4
    Debiancc  
       2018-03-15 16:59:50 +08:00
    javascript``
    class AccountDrawer extends MyDrawer {

    menu = "account";

    static MenuItem() {

    }

    render() {
    return (
    <Drawer open={this.isOpen(this.props.status)}>
    <AppBar title="账号管理"
    showMenuIconButton={false}
    onTitleClick={this.props.close}/>
    <MenuItem>角色列表</MenuItem>
    <MenuItem>用户列表</MenuItem>
    </Drawer>
    );
    }
    }
    ``
    TabGre
        5
    TabGre  
       2018-03-15 17:46:13 +08:00
    感觉学 React 和 material ui 没有必要一起的,容易弄蒙
    lllpla
        6
    lllpla  
       2018-03-15 18:04:03 +08:00
    首先我也是初学者,我只说下我自己的理解不知道对不对啊。

    针对第二个问题我是会再创建一个 class, MyMenu,然后这里 iconElementLeft={<MyMenu xxx=xxx />}

    然后在 MyMenu 的 render、和 componentWillMount 方法里面去写一些判断和逻辑

    class MyMenu extends React.Component{
    componentWillMount(){}
    render(){

    }

    }
    lllpla
        7
    lllpla  
       2018-03-15 18:14:11 +08:00
    刚才没写完点错了



    class MyMenu extends React.Component{
    constructor(e){
    super(e)
    this.state={}
    }
    componentWillMount(){
    //异步请求获取菜单 json
    HttpUtil.getMenu()
    .then(res=>{
    this.setState(menus:res)
    })
    }
    render(){
    onClick = this.props.onClick //如果需要参数的话 可以通过这个传递
    if(!this.state.menus){
    return(<div></div>)
    }

    return(
    <div>
    {this.state.menus.map(
    menu=>(<MenuItem primaryText={menu.text} onClick={onClick}>...</MenuItem>)
    )}
    </div>
    )

    }
    }
    export default MyMenu
    popbones
        8
    popbones  
       2018-03-15 18:37:13 +08:00 via iPhone
    1. 如果你的环境支持 static var 用 static var,要不行用 static getter,再不行 global const
    2. 你可以从 state 或 props 里读 IconMenu,在加载或适当的时候从服务器获取列表存入 state 或 forceupdate
    3. Render 可以 call 其它返回(<JSX>) 的方法

    不过我这些都是 react native,应该差不多吧
    lolizeppelin
        9
    lolizeppelin  
    OP
       2018-03-15 18:51:24 +08:00
    谢谢楼上 要的就是

    我以为
    {this.state.menus.map(
    menu=>(<MenuItem primaryText={menu.text} onClick={onClick}>...</MenuItem>)
    )}
    只能返回类似[]

    原来可以直接用在
    <div></div>中
    lolizeppelin
        10
    lolizeppelin  
    OP
       2018-03-15 20:03:16 +08:00
    1. 如果你的环境支持 static var 用 static var,要不行用 static getter,再不行 global const

    这写法我知道, 但是太不优雅 肯定不这么写
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2710 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 10:25 · PVG 18:25 · LAX 02:25 · JFK 05:25
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.