如何根据另一个组件的状态更改css属性

时间:2019-12-23 15:06:06

标签: javascript reactjs gatsby

我正在使用gatsby构建一个基于react的网页,并且每次打开Gallery组件的模态时,我都需要我的nav组件将其粘性位置更改为相对或自动。不知道如何解决和解决问题。导航组件属于布局组件,而布局组件是Gallery的父组件。以下是其中涉及的组件:

导航组件:

import React, { Component } from 'react'
import { Location } from '@reach/router'
import { Link } from 'gatsby'
import { Menu, X } from 'react-feather'
import Logo from './Logo'

import './Nav.css'

export class Navigation extends Component {
  state = {
    active: false,
    activeSubNav: false,
    currentPath: false
  }

  componentDidMount = () =>
    this.setState({ currentPath: this.props.location.pathname })

  handleMenuToggle = () => this.setState({ active: !this.state.active })

  // Only close nav if it is open
  handleLinkClick = () => this.state.active && this.handleMenuToggle()

  toggleSubNav = subNav =>
    this.setState({
      activeSubNav: this.state.activeSubNav === subNav ? false : subNav
    })

  render() {
    const { active } = this.state,
    { subNav } = this.props,
      NavLink = ({ to, className, children, ...props }) => (
        <Link
          to={to}
          className={`NavLink ${
            to === this.state.currentPath ? 'active' : ''
          } ${className}`}
          onClick={this.handleLinkClick}
          {...props}
        >
          {children}
        </Link>
      )

    return (
      <nav className={`Nav ${active ? 'Nav-active' : ''}`}>

        <div className="Nav--Container container">
             <Link to="/" onClick={this.handleLinkClick}>
                <div style={{ width: `40px`, margin:`0 20px`}}>
                   <Logo />
                </div>
             </Link>

          <div className="Nav--Links">
          <NavLink to="/">Home</NavLink>
          <NavLink to="/contact/">Contacto</NavLink>

            <div className={`Nav--Group ${this.state.activeSubNav === 'about' ? 'active' : '' }`} > 

                 <span className={`NavLink Nav--GroupParent ${
                   this.props.location.pathname.includes('about') ||
                   this.props.location.pathname.includes('team') ||
                   this.props.location.pathname.includes('news') 
                   ? 'active'
                    : ''
                 }`} 
                       onClick={() => this.toggleSubNav('about')}
                 >
                     Nosotros
                 </span>
                 <div className="Nav--GroupLinks">
                    {subNav.map( (link, index)=> (
                        <NavLink 
                        to={link.link} 
                        key={'posts-subnav-link-' + index}
                        className="Nav--GroupLink">{link.name}</NavLink>
                    ))}
                 </div>

            </div>

          </div>

          <button
            className="Button-blank Nav--MenuButton"
            onClick={this.handleMenuToggle}
          >
            {active ? <X /> : <Menu />}
          </button>

        </div>

      </nav>
    )
  }
}

export default ({ subNav }) => (
  <Location>{route => <Navigation subNav={subNav} {...route} />}</Location>
)


在nav.css文件中,默认位置属性设置为粘滞,我想将其删除并更改 动态地取决于模态画廊的状态(打开或关闭)。

这是我的图库组件:

import React, { useState, useCallback } from "react";
import Gallery from "react-photo-gallery";
import Carousel, { Modal, ModalGateway } from "react-images";

const PhotoGallery = ({photos}) => {
  const [currentImage, setCurrentImage] = useState(0);
  const [viewerIsOpen, setViewerIsOpen] = useState(false);

  const openLightbox = useCallback((event, { photo, index }) => {
    setCurrentImage(index);
    setViewerIsOpen(true);
  }, []);

  const closeLightbox = () => {
    setCurrentImage(0);
    setViewerIsOpen(false);
  };

   return(
     <div>
         <Gallery photos={photos} onClick={openLightbox} />
            <ModalGateway>
                {viewerIsOpen ? (
                   <Modal onClose={closeLightbox}>
                   <Carousel
                    currentIndex={currentImage}
                    views={photos.map(x => ({
                    ...x,
                    srcset: x.srcSet,
                    caption: x.title
                  }))}
            />
          </Modal>
        ) : null}
      </ModalGateway>
     </div>
   )
}

export default PhotoGallery

问题在于,当模式打开时,导航栏仍然很粘,并且不允许我访问模式控件,例如关闭和展开...而我需要更改它。

1 个答案:

答案 0 :(得分:0)

有几种解决方法。

  1. 旧学校的班级名称切换

    将道具传递到反映状态的子组件。在孩子身上,使用该道具有条件地渲染一个或多个表示所需演示文稿的类。

  2. 通过style道具分配样式

    这与#1类似,但是消除了抽象层。无需组装类列表,而只是组装要用作对象的CSS样式。

    const Component = ({ someState }) => 
      <div style={someState ? { border: "5px solid red" } : { color: "#999" }}>
        Some Text
      </div>
    
  3. 使用CSS-in-JS库

    上述方法的缺点是您最终在页面上为元素的每个实例复制样式。 CSS-in-JS库通过将样式提取到自动生成的类中并将该类应用于您的组件来解决此问题。我更喜欢Emotion,但还有其他人。

    使用Emotion,您可以接受父级的className道具,该道具将覆盖子级设置的默认值。这种控制反转功能非常强大,并解决了早期CSS-in-JS方法的许多缺点。

    const ParentComponent = () => {
      const [someState] = useState(false)
      return <ChildComponent css={{ color: someState ? "blue" : "red" }} />
    }
    
    const ChildComponent = ({ className }) =>
      <div
        css={{
          color: "#000",
          border: "4px solid currentColor"
        }}
        className={className}
      >
        Some Text
      </div>
    

    在上面的示例中,{Emotion}使用生成的类名来分配className,该类名是根据css内部传递给ChildComponent的{​​{1}}道具分配的。当ParentComponentdiv(默认)时,其结果将是带有蓝色边框和蓝色文本的someState。将false切换为someState时,边框和文字将变为红色。这是因为通过true传递的样式将覆盖直接在Emotion中通过className分配的样式。

相关问题