将背景图像设置为反应中的道具

时间:2018-04-09 19:31:24

标签: reactjs

我有一个react组件需要从父Play组件中获取背景图像,而不是在样式表中设置。我试图将它作为道具传递给组件,但不确定如何使其工作:

主要组件

import React from 'react'
import ReactDOM from 'react-dom'
import DeviceBlock from '/DeviceBlock/DeviceBlock'

const Play = {
  init() {
    const container = document.getElementById('blocker-container');
    if(container) {
      ReactDOM.render(
        <DeviceBlock
        backgroundImage={'background-image-url.png'}
        logo={'url-to-logo.png'} />,
        container
      )
    }
  }
}

document.addEventListener('DOMContentLoaded', () => {
  Play.init()
})

阻止导入上述播放组件的组件

import React from 'react'
import './DeviceBlock.scss'

function DeviceBlock (props) {
  constructor(props) {
    super(props)
    this.state = {
      backgroundImage: backgroundImage,
      logo: logo;
    }
  }
  return (
    <div className='device-blocking' style={this.state.backgroundImage}>
      <div className='container'>
        <div className='logo'>
          <img src='{{this.state.logo}}' />
        </div>
        <div className='message'>
          <h1>Content</h1>
          <a href='/' className='btn btn--primary btn--lg'>Link</a>
        </div>
      </div>
    </div>
  )
}

export default DeviceBlock

3 个答案:

答案 0 :(得分:6)

你应该导入你的背景img

import BackgroundImage from '...png'; // Relative Path to BackgroundImage
import Logo from '...png'; // Relative Path to Logo

并在你的州

this.state = {
  backgroundImage: `url(${BackgroundImage})`,
  logo: Logo
};

另外,我注意到您的<img>错了

<img src='{{this.state.logo}}' />

应该是

<img src={this.state.logo} />

另请注意,我看到您在函数中添加了构造函数。 如果要创建具有状态的react组件,则需要使组件成为类。

class DeviceBlock extends React.Component { 
  constructor(props) {
    super(props);
    this.state = {}
  }
  render() { 
    ...
  }
}
  

编辑:这是基于传递道具的编辑更新代码。

import React from 'react'
import ReactDOM from 'react-dom'
import DeviceBlock from '/DeviceBlock/DeviceBlock'
import BackgroundImage from '../url-to-background.png'; // Path to BackgroundImage
import Logo from 'url-to-logo.png'; // Relative Path to Logo

const Play = {
  init() {
    const container = document.getElementById('blocker-container');
    if (container) {
      ReactDOM.render(
        <DeviceBlock
          backgroundImage={BackgroundImage}
          logo={Logo} 
        />,
        container
      )
    }
  }
}

document.addEventListener('DOMContentLoaded', () => {
  Play.init()
})

import * as React from 'react'
import './DeviceBlock.scss'

function DeviceBlock (props) {
  return (
    <div 
      className='device-blocking' 
      style={{ backgroundImage: `url(${props.backgroundImage})` }}
    >
      <div className='container'>
        <div className='logo'>
          <img src={props.logo} />
        </div>
        <div className='message'>
          <h1>Content</h1>
          <a href='/' className='btn btn--primary btn--lg'>Link</a>
        </div>
      </div>
    </div>
  );
}

export default DeviceBlock

注意我的解决方案仅在您的图像来自您自己的服务器并从webpack处理而不是从其他URL处理时才有效。

如果图片来自其他网址,则不应导入网址并将其直接添加到道具

<DeviceBlock
  backgroundImage="url-to-background.png",
  logo="url-to-logo.png"
/>

答案 1 :(得分:4)

样式是一个对象尝试使用

style={{backgroundImage: this.state.backgroundImage}}

此外,您不能在功能组件中使用构造函数和使用状态。将组件转换为常规反应组件并保持状态。或者将状态部分放在常规反应组件中并将其作为道具传递到功能组件中。 @Kenneth Truong的回答中也提到了这一点

要将其转换为常规反应组件,您可以执行以下操作

class DeviceBlock extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      backgroundImage: "url('url-to-background.png')",
      logo: "url('url-to-logo.png')";
    }
  }
  render() {
    return (
      <div className='device-blocking' style={{backgroundImage: this.state.backgroundImage}}>
        <div className='container'>
          <div className='logo'>
            <img src='{{this.state.logo}}' />
          </div>
          <div className='message'>
            <h1>Content</h1>
            <a href='/' className='btn btn--primary btn--lg'>Link</a>
          </div>
        </div>
      </div>
    )
  }
}

你可以看到它在这里工作 https://codepen.io/anon/pen/zWexzO

更新

根据更新的问题,您还可以将其保留为功能组件并传递道具

class App extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      backgroundImage: "url('url-to-background.png')",
      logo: "url('url-to-logo.png')";
    }
  }
  render() {
    return (
      <DeviceBlock 
        backgroundImage={this.state.backgroundImage}
        logo={this.state.logo}/>
    )
  }
}

const DeviceBlock = (props) => {
    return (
      <div className='device-blocking' style={{backgroundImage: props.backgroundImage}}>
        <div className='container'>
          <div className='logo'>
            <img src='{{props.logo}}' />
          </div>
          <div className='message'>
            <h1>Content</h1>
            <a href='/' className='btn btn--primary btn--lg'>Link</a>
          </div>
        </div>
      </div>
    )
} 

https://codepen.io/anon/pen/OvdPOQ

app组件只是表明你可以传递一些动态状态。您当然可以直接从Play.init函数渲染DeviceBlock组件,就像在提供的代码中一样(然后您可以忽略App组件部分)

答案 2 :(得分:0)

我能够通过将图像传递到父级中的<DeviceBlock />来获取要在子组件中显示的图像,如下所示:

<DeviceBlock
    backgroundImage="background-image-url.png"
    logo="logo-image-url.png" />,
    container

然后将它们作为孩子的道具

<div className='device-blocking' style={{ backgroundImage: `url(${props.backgroundImage})` }}>
  <div className='container'>
    <div className='logo'>
      <img src={props.logo} />
    </div>
    <div className='message'>
      <h1>Content</h1>
      <a href='/' className='btn btn--primary btn--lg'>Link text</a>
    </div>
  </div>
</div>