【问题标题】:Hide Elements based on role根据角色隐藏元素
【发布时间】:2021-12-01 00:50:15
【问题描述】:

我正在使用 react 和 Firebase,并为幼儿园制作了一个应用。现在,我有一些不应该对父母可见的组件。有没有一种简单的方法可以做到这一点?这是我的第一个应用,尤其是 Firebase 和 react。

我正在考虑检查角色,然后只是一个简单的 if else 语句。我不确定这是否是一个好的逻辑。

更新

我的用户挂钩:

export function useAllUsers() {
  const [users, setUsers] = useState([]);

  useEffect(() => {
    const usersCollected = [];
    firebase
      .firestore()
      .collection("users")
      .get()
      .then((snapshot) => {
        snapshot.forEach((doc) => {
          usersCollected.push({
            ...doc.data(),
            uid: doc.id,
          });
        });
        setUsers(usersCollected);
        console.log(usersCollected);
      });
  }, []);
  return users;
}

日历:

function DateAndTimePickers() {
  const classes = useStyles();
  const [ort, setOrt] = useState("");
  const [notiz, setNotiz] = useState("");
  const [hinweis, setHinweis] = useState("");
  const [eintragen, setEintragen] = useState([]);
  const [dateandtime, setDateandtime] = useState([]);
 

  function handelDateandTime(e) {
    setDateandtime(e.target.value);
  }
  function handelOrt(e) {
    setOrt(e.target.value);
  }
  function handelNotiz(e) {
    setNotiz(e.target.value);
  }
  function handelHinweis(e) {
    setHinweis(e.target.value);
  }
  function KalenderEintrag() {
    db.collection("eintrag")
      .doc()
      .set({
        ort,
        notiz,
        hinweis,
        dateandtime,
      })
      .then(() => {

        setEintragen([...eintragen, { ort, notiz, hinweis, dateandtime }]);
        console.log("Documents saved succesfully");
      })
      .catch((err) => {
        console.log(err);
      });
  }

  function fetchKalendareintrag() {
    firebase
      .firestore()
      .collection("eintrag")
      .get()
      .then((snapshot) => {
        let loadedIfnos = snapshot.docs.map((doc) => {
          console.log(doc.data());
          return doc.data();
        });
        setEintragen(loadedIfnos);
      });
  }

  useEffect(() => {
    fetchKalendareintrag();
  }, []);

  return (


//hide
        <ScrollView style={styles.root}>
          <Container>
            <TextField
              id="datetime-local"
              label="Neues Ereigniss"
              type="datetime-local"
              defaultValue="2021-09-16T10:30"
              className={classes.root}
              InputLabelProps={{
                shrink: true,
              }}
              onChange={(value) => {
                handelDateandTime(value);
              }}
            />
      </Container>
      {/* ORT */}
      <Container className={classes.ortContainer}>
        <TextField
          id="standard-helperText"
          label="Ort"
          defaultValue="Text"
          onChange={(value) => {
            handelOrt(value);
          }}
        />
      </Container>
      {/* Hinweis */}
      <Container className={classes.ortContainer}>
        <TextField
          id="standard-helperText"
          label="Hinweis"
          defaultValue="Text"
          onChange={(value) => {
            handelHinweis(value);
          }}
        />
      </Container>
      {/* Notizen */}
      <Container className={classes.ortContainer}>
        <TextField
          id="standard-helperText"
          label="Notizen"
          defaultValue="Text"
          onChange={(value) => {
            handelNotiz(value);
          }}
        />
      </Container>
      

      <Container>
        <Button onClick={() => KalenderEintrag()}  className={classes.btn} variant="outlined">Absenden</Button>
      </Container>
//Show 
      {/* Kalender einträge  */}
      {/* Kalender einträge  */}
      {eintragen.map((item) => {
        return (
          <Card className={classes.card}>
          <CardContent>
            <Typography
              className={classes.title}
              color="textSecondary"
              gutterBottom
            >
              {item.ort}
            </Typography>
            <Typography variant="h5" component="h2">
              {item.hinweis}
            </Typography>
            <Typography className={classes.pos} color="textSecondary">
              {item.notiz}
            </Typography>
            <Typography variant="body2" component="p">
              {item.dateandtime}
              <br />
             
            </Typography>
          </CardContent>
          <CardActions>
            
          </CardActions>
        </Card>
        )
      })}
    </ScrollView>
  );
}



const mapStateToProps = (store) => ({
  eintrag: store.userState.currentUser,
 
});
export default connect(mapStateToProps, null)(DateAndTimePickers);

【问题讨论】:

    标签: reactjs firebase react-native


    【解决方案1】:

    简单的if else 语句或switch 块可用于检查角色,但随着应用程序开始增长,管理所有基于角色的逻辑将是一项乏味的任务。这一切都与您如何设置架构以处理基于 role 的流程有关。

    我也遇到过类似的流程。

    您可以做的是创建挂钩,例如 useHasRolesuseUser

    useHasRoles 钩子将检查您当前登录的用户是否具有指定的角色。为了获取当前用户的详细信息,我们使用了另一个挂钩 useUser,它将返回该特定用户的当前用户详细信息和角色。

    useHasRoles(挂钩)

    const useHasRoles =(roleNames)=>{
    const roles =  useUser();
    
    if (typeof roleNames === "string") {
      //check whether current user has specific role or not
      //return true/false
      } else if (Array.isArray(roleNames)) {
       //check if current user has all roles specified in roleNames
      //return true/false
      } else {
        return false;
      }
    }
    

    useUser(挂钩)

    const useUser = ()=>{
       //get current user details and roles.
       return {roles:[]}
    }
    

    如何使用?

    const sample = ()=>{
        const hasAdminRole = useHasRoles('ADMIN') // ['ADMIN', 'SUPERADMIN']
        // you can pass roles as array, so it will check for all the roles.
    }
    

    如果有帮助,请告诉我。

    【讨论】:

    • 如果我想使用角色,我已经有一个用户挂钩,我需要稍微改变一下,还是?
    • 您可以更改您的用户挂钩,使其具有当前访问用户的所有角色。稍后在useHasRoles钩子中,您可以使用当前用户的角色检查传递的角色
    【解决方案2】:

    有很多方法可以做到这一点。

    这是一个简单的 TextButton,如果用户是父母,它会被禁用:

    interface Props {
      onPress: () => void
      children: string
      userRole: UserRole
    }
    
    const TextButton = ({ onPress, children, userRole }: Props) => {
      const disabled = userRole === UserRole.Parent
    
      return (
        <TouchableOpacity
          activeOpacity={1}
          style={styles.button}
          onPress={onPress}
          disabled={disabled}>
          <Text
            style={styles.text}
            {children}
          </Text>
        </TouchableOpacity>
      )
    }

    这里我使用了带有条件渲染元素的模态。

    <Modal {...{ isVisible, onClose, hasBackdrop, displayName: Alert.displayName }}>
          <View style={[styles.container, getType(), { paddingBottom }]}>
            {isCloseIcon && (
              <TouchableOpacity style={styles.closeContainer} onPress={onClose}>
                <SvgView testID={alertCloseIcon} svg={<IconClose style={styles.closeIcon} />} />
              </TouchableOpacity>
            )}
            <View style={styles.content}>
              <SvgView style={styles.closeIconContainer} svg={icon} />
              <Text testID={alertTitle} style={getTextStyles()}>
                {title}
              </Text>
              {!!subtitle && (
                <Text testID={alertSubtitle} style={styles.subtitle}>
                  {subtitle}
                </Text>
              )}
            </View>
          </View>
        </Modal>
    

    【讨论】:

    • @DavidShimonBaars 我更新了帖子,因为我也喜欢您的解决方案,但我想知道您将如何实施?我以前尝试过这样的事情,但我得到的只是错误哈哈,所以我做错了。在 Calendar.js 上有我想隐藏和显示的部分 cmets。 :)
    • 您遇到了什么错误?我在答案中添加了另一个示例。
    【解决方案3】:

    我找到了一种更简单的方法:D 我已经有了一个用户钩子,所以我不需要做任何额外的事情,因为我正在检查我的用户集合中的角色。我所要做的就是检查角色。也许这不是背心的解释,但英语不是我的母语,这是我能做的最好的:')。 如果有人遇到同样的问题,我希望这会有所帮助! 感谢@DovidShimonBaars 和@ShubhamJajoo

    {user?.role === "parent" && (
            <>
              <Container>
                <TextField
                  id="datetime-local"
                  label="Neues Ereigniss"
                  type="datetime-local"
                  defaultValue="2021-09-16T10:30"
                  className={classes.root}
                  InputLabelProps={{
                    shrink: true,
                  }}
                  onChange={(value) => {
                    handelDateandTime(value);
                  }}
                />
              </Container>
              {/* ORT */}
              <Container className={classes.ortContainer}>
                <TextField
                  id="standard-helperText"
                  label="Ort"
                  defaultValue="Text"
                  onChange={(value) => {
                    handelOrt(value);
                  }}
                />
              </Container>
              {/* Hinweis */}
              <Container className={classes.ortContainer}>
                <TextField
                  id="standard-helperText"
                  label="Hinweis"
                  defaultValue="Text"
                  onChange={(value) => {
                    handelHinweis(value);
                  }}
                />
              </Container>
              {/* Notizen */}
              <Container className={classes.ortContainer}>
                <TextField
                  id="standard-helperText"
                  label="Notizen"
                  defaultValue="Text"
                  onChange={(value) => {
                    handelNotiz(value);
                  }}
                />
              </Container>
           
        
    
          <Container>
            <Button
              onClick={() => KalenderEintrag()}
              className={classes.btn}
              variant="outlined"
            >
              Absenden
            </Button>
          </Container>
          </>  )}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-09-01
      • 2018-08-09
      • 2012-06-20
      • 2018-04-23
      • 1970-01-01
      • 2021-08-31
      • 2021-08-05
      • 2017-12-13
      相关资源
      最近更新 更多