Почему css моего реагирующего компонента не обновляется динамически? - PullRequest
1 голос
/ 08 июня 2019

Я добавил избыточность для создания-реакции-приложения, и я пытался заставить работать навигатор.Я делаю это, выделяя активную «ссылку на страницу».Код, который я использую для этого, представляет собой комбинацию реагирующих хуков (использующих состояние для запоминания текущей страницы) и пакета имен npm classNames.

classNames (object ['key'] && classes.activeItem)

Так что здесь у меня есть объект ['key'], оцениваемый в true, когда этот конкретный элемент активирован, так что элемент получаетactiveItem class.

Когда я заменяю object ['key'] на true, это работает.Когда я открываю объект console.log ['key'] после нажатия на него, он также оценивается как true.

Почему это не работает?Спасибо!

import React, { useEffect, memo } from 'react';
import { bindActionCreators, compose } from 'redux';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { withStyles } from '@material-ui/core/styles';
import { loadPage } from './actions';
import { uploadFile } from '../uploadFile/actions';
import _ from 'lodash';


const styles = theme => ({
  item: {
    paddingTop: 4,
    paddingBottom: 4,
    color: 'rgba(255, 255, 255, 0.7)',
    '&:hover': {
      backgroundColor: 'rgba(255, 255, 255, 0.08)',
    },
  },
  itemPrimary: {
    color: 'inherit',
    fontSize: theme.typography.fontSize,
    '&$textDense': {
      fontSize: theme.typography.fontSize,
    },
  },
  itemActiveItem: {
    color: '#4fc3f7',
  },
  textDense: {}
});

function Navigator(props) {
  const { classes, curPage, onUploadFile, onPageChange, dispatch, ...other } = props;

  let activePage = {
    'invite': false,
  }

  useEffect(() => {
    if(!curPage){
      onPageChange('search');
    }
    activePage = _.mapValues(activePage, () => false);
    activePage[curPage] = true
  });


  return (
    <Drawer variant="permanent" {...other}>
      <List disablePadding>
        <ListItem button className={classNames(classes.logo)}>
          <img src={require("assets/img/logo.png")} alt={''}/>
        </ListItem>

        <ListItem className={classes.categoryHeader} >
          <ListItemText classes={{ primary: classes.categoryHeaderPrimary }}>
            Files
          </ListItemText>
        </ListItem>

        <ListItem
          button
          dense
          className={classNames(classes.item, activePage['invite'] && classes.itemActiveItem)}
          onClick={() => {onPageChange('invite')}}
          >
          <ListItemIcon><PeopleIcon /></ListItemIcon>
          <ListItemText classes={{ primary: classes.itemPrimary, textDense: classes.textDense }}>
            Invite To Your Team
          </ListItemText>
        </ListItem>

      </List>

    </Drawer>
  );
}

Navigator.propTypes = {
  classes: PropTypes.object.isRequired,
  onPageChange: PropTypes.func.isRequired,
  onUploadFile: PropTypes.func.isRequired
};

const mapStateToProps = (state) => {
  const { curPage } = state.app;
  return { curPage };
};

const mapDispatchToProps = (dispatch) => {
  return {
    onPageChange: bindActionCreators(loadPage, dispatch),
    onUploadFile: bindActionCreators(uploadFile, dispatch),
    dispatch
  };
};

const withConnect = connect(
  mapStateToProps,
  mapDispatchToProps
);


export default compose(withConnect, memo, withStyles(styles))(Navigator);

1 Ответ

1 голос
/ 08 июня 2019

Обратите внимание, что функция, переданная хуку useEffect, всегда запускается после рендеринга .

Ваш useEffect не вызывает повторного рендеринга для компонента, чтобы увидеть изменения,Только изменение состояния вызывает повторную визуализацию.Если вы хотите выполнить повторный рендеринг, вам сначала нужно использовать useState hook, а затем вам нужно setState изнутри useEffect hook.Или вы можете просто запустить эти две строки как часть рендера (удалив их из хука useEffect, поместив их снаружи):

activePage = _.mapValues(activePage, () => false);
activePage[curPage] = true
useEffect(() => {
    if(!curPage){
      onPageChange('search');
    }
});

Но когда я смотрю на ваш код, я думаю,Вы можете просто использовать curPage === 'invite' && classes.itemActiveItem вместо activePage['invite'] && classes.itemActiveItem и удалить ненужные строки, связанные с объектом activePage.Было бы намного проще.

...