【问题标题】:Change background of parent after Match匹配后更改父母的背景
【发布时间】:2017-09-14 19:29:05
【问题描述】:

我对反应很陌生... 我有一个父组件,它代表我的 web 应用程序的背景。当用户导航到不同的路由时,我使用来自 react-router 的 Match 来处理。

新路由会渲染 PageView 组件,我希望它有不同的背景图片。所以要做到这一点,我通过将一个函数从父级传递给他的子级道具,然后在子级中从 componentDidMount() 调用它来设置它的父级的背景图像

这不起作用并给我Maximum call stack exceeded 错误

这是我的父组件:

class App extends Component {
  constructor () {
    super()
    this.state = {
      backgroundImage: '../public/img/initial.jpg'
    }

    this.changeBackground = this.changeBackground.bind(this)
  }
  changeBackground (backgroundImage) {
    this.setState({
      backgroundImage
    })
  }
  render () {
    return (
      <BrowserRouter>
        <Provider store={store}>
          <div className='app' style={{backgroundImage: `url(${this.state.backgroundImage})`}}>
            <div className='overlay'>
              <Match exactly pattern='/' component={() => <Landing />}
              />
              <Match
                pattern='/healthcare'
                component={(props) => <PageView descriptionText='Healthcare Solutions'
                  backgroundImage='../public/img/5.png' changeParentBackground={this.changeBackground} {...props} />}
              />
              <Match
                pattern='/officeofthefuture'
                component={(props) => <PageView descriptionText='Office of the Future'
                  backgroundImage='../public/img/1.png' changeParentBackground={this.changeBackground} {...props} />}
              />
            </div>
          </div>
        </Provider>
      </BrowserRouter>
    )
  }
}

这是我的子组件 PageView

class PageView extends Component {
  componentDidMount () {
    const { backgroundImage, changeParentBackground } = this.props
    changeParentBackground(backgroundImage)
  }
  render () {
    const { descriptionText } = this.props
    console.log(this.props.changeParentBackground)
    return (
      <div className='outerDiv'>
        <LeftDesign show />
        <RightDesign descriptionText={descriptionText} />
      </div>
    )
  }
}

正确设计:

class RightDesign extends Component {
  render () {
    const { descriptionText } = this.props
    return (
      <div className='rightDiv'>
        <div id='bigCircle'>
          <div className='bigCircleTextDiv'>
            <h1 className='bigCircleText'>{descriptionText}</h1>
          </div>
        </div>
      </div>
    )
  }
}

左设计

class LeftDesign extends Component {
  constructor (props) {
    super(props)
    const { show } = this.props
    this.state = {show}
  }
  render () {
    return (
      <div className='leftDivContainer'>
        <div className='leftDiv'>
          {this.state.show && <WelcomeMsg />}
        </div>
      </div>
    )
  }
}

【问题讨论】:

  • 这段代码看起来不错,我认为问题出在LeftDesignRightDesign 组件中,你能也显示这些组件吗?
  • @MayankShukla 请查看我添加了组件的已编辑问题
  • 因此您可以读取父级的 Location 属性对象以确定您在哪个页面上。将 'this.props.location.pathname' 拆分为 '/' 并拉取第二个数组项以找到您的第一级路由字符串并使用 switch 语句来确定背景图像。

标签: reactjs ecmascript-6 react-router


【解决方案1】:

我之前评论过这种解决方案。

它使用 CSS 背景图像和过渡,根据位置路径名的第二项字符串是什么来切换图像,这将对应于您应用的一级路由。

function getBackground(array) {
  switch(array[1]) { 
   case 'healthcare':
    return 'www.foo.com/image/1.jpg';
   case 'officeofthefuture':
    return 'www.foo.com/image/2.jpg';
   default:
    return 'www.foo.com/image/default.jpg'
  }
}

export default class Parent extends Component {
  render() {
   let { location } = this.props;

   // Split the pathname string into an array of sub-paths
   let locationArray = location ? location.pathname.split('/') : [];

   // Determine the Background URL
   let backgroundUrl = getBackground(locationArray);
   // Define the Parent Style
   const parentStyle = {
     transition: 'all 0.2s ease-out',
     backgroundImage: "url('"+backgroundUrl+"')",
     backgroundPosition: 'center',
     backgroundSize: 'contain',
     backgroundRepeat: 'no-repeat'
   };
   return <div style={parentStyle}>
            {this.props.children}
          </div>
  }
}

【讨论】:

  • 谢谢!这有效..但有一个问题。当我刷新任何路由时,我收到以下“警告:warning.js:36 警告:React 试图在容器中重用标记但校验和无效。这通常意味着您正在使用服务器渲染和生成的标记服务器不是客户端所期望的。React 注入了新的标记来补偿哪些工作,但您已经失去了服务器渲染的许多好处。相反,弄清楚为什么生成的标记是......“如何修复?
  • 你在使用服务器端渲染(通用/同构)吗?
  • 通用渲染
  • 好的,看看这个link。您可能必须将服务器端呈现的内容包装在 div 中,以补偿 React 在客户端呈现的方式。编辑:看看詹姆斯赖特的答案,它没有标记,但它是最佳答案。
  • 所以在阅读了一番之后,实际上阅读了我刚刚链接的整篇文章(哎呀),如果您使用一些自动前缀与内联样式相结合,这可能是一个问题。很难准确猜测可能引发此错误的原因。抱歉,据我所知,我写的答案适用于非通用解决方案。
猜你喜欢
  • 1970-01-01
  • 2017-12-30
  • 1970-01-01
  • 2011-10-24
  • 1970-01-01
  • 1970-01-01
  • 2017-08-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多