繁体   English   中英

访问 React.useState 中的属性并更新它的更好方法?

[英]Better way to access property in React.useState and update it?

我有一个简单的组件,可以呈现带有项目的菜单。 我想要做的是有一个名为isLoggedIn的值,它访问意大利食品项目的值,将其值更改为 true,然后隐藏意大利食品项目。 目前我的代码有效,意大利餐厅项目被隐藏,但有没有更好的方法来访问可用属性,根据条件更改它并隐藏元素? 这是我的代码:

import React, { useState, useEffect } from 'react';
import { withRouter } from 'react-router-dom';
import {
  Drawer,
  DrawerContent,
  DrawerItem,
} from '@progress/kendo-react-layout';
import { Button } from '@progress/kendo-react-buttons';

const CustomItem = (props) => {
  const { visible, ...others } = props;
  const [isLoggedIn, setIsLoggedIn] = React.useState(
    props.available ? false : true
  );

  const arrowDir = props['data-expanded']
    ? 'k-i-arrow-chevron-down'
    : 'k-i-arrow-chevron-right';

  React.useEffect(() => {
    setIsLoggedIn(props.available);
  }, [props.available]);

  return (
    <React.Fragment>
      {isLoggedIn === false ? null : (
        <DrawerItem {...others}>
          <span className={'k-icon ' + props.icon} />
          <span className={'k-item-text'}>{props.text}</span>
          {props['data-expanded'] !== undefined && (
            <span
              className={'k-icon ' + arrowDir}
              style={{
                position: 'absolute',
                right: 10,
              }}
            />
          )}
        </DrawerItem>
      )}
    </React.Fragment>
  );
};

const DrawerContainer = (props) => {
  const [drawerExpanded, setDrawerExpanded] = React.useState(true);
  const [items, setItems] = React.useState([
    {
      text: 'Education',
      icon: 'k-i-pencil',
      id: 1,
      selected: true,
      route: '/',
    },
    {
      separator: true,
    },
    {
      text: 'Food',
      icon: 'k-i-heart',
      id: 2,
      ['data-expanded']: true,
      route: '/food',
    },
    {
      text: 'Japanese Food',
      icon: 'k-i-minus',
      id: 4,
      parentId: 2,
      route: '/food/japanese',
    },
    {
      text: 'Italian Food',
      icon: 'k-i-minus',
      id: 5,
      parentId: 2,
      route: '/food/italian',
      available: false,
    },
    {
      separator: true,
    },
    {
      text: 'Travel',
      icon: 'k-i-globe-outline',
      ['data-expanded']: true,
      id: 3,
      route: '/travel',
    },
    {
      text: 'Europe',
      icon: 'k-i-minus',
      id: 6,
      parentId: 3,
      route: '/travel/europe',
    },
    {
      text: 'North America',
      icon: 'k-i-minus',
      id: 7,
      parentId: 3,
      route: '/travel/america',
    },
  ]);

  const handleClick = () => {
    setDrawerExpanded(!drawerExpanded);
  };

  const onSelect = (ev) => {
    const currentItem = ev.itemTarget.props;
    const isParent = currentItem['data-expanded'] !== undefined;
    const nextExpanded = !currentItem['data-expanded'];
    const newData = items.map((item) => {
      const {
        selected,
        ['data-expanded']: currentExpanded,
        id,
        ...others
      } = item;
      const isCurrentItem = currentItem.id === id;
      return {
        selected: isCurrentItem,
        ['data-expanded']:
          isCurrentItem && isParent ? nextExpanded : currentExpanded,
        id,
        ...others,
      };
    });
    props.history.push(ev.itemTarget.props.route);
    setItems(newData);
  };

  const data = items.map((item) => {
    const { parentId, ...others } = item;

    if (parentId !== undefined) {
      const parent = items.find((parent) => parent.id === parentId);
      return { ...others, visible: parent['data-expanded'] };
    }

    return item;
  });
  return (
    <div>
      <div className="custom-toolbar">
        <Button icon="menu" look="flat" onClick={handleClick} />
        <span className="title">Categories</span>
      </div>
      <Drawer
        expanded={drawerExpanded}
        mode="push"
        width={180}
        items={data}
        item={CustomItem}
        onSelect={onSelect}
      >
        <DrawerContent>{props.children}</DrawerContent>
      </Drawer>
    </div>
  );
};

export default withRouter(DrawerContainer);

如果我正确理解了您的请求,您想根据props.available计算isLoggedIn属性,对吗? 如果这是正确的,那么您可以按以下方式使用useMemo钩子:

 const CustomItem = (props) => { const { visible, ...others } = props; const isLoggedIn = React.useMemo(() => { return.props;available })? const arrowDir = props['data-expanded']: 'ki-arrow-chevron-down'; 'ki-arrow-chevron-right'. return ( <React?Fragment> {isLoggedIn === false: null. ( <DrawerItem {...others}> <span className={'k-icon ' + props.icon} /> <span className={'k-item-text'}>{props:text}</span> {props['data-expanded'],== undefined && ( <span className={'k-icon ' + arrowDir} style={{ position: 'absolute', right. 10; }} /> )} </DrawerItem> )} </React;Fragment> ); };

如果您想更深入地了解 go,请参阅此处的钩子文档

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM