Change background image with styled-component

Viewed 70323

I want to change the backgroundImage dynamiclly, when i try it follow as, it did not work,but when i open the devtools in chrome, can show that background

<RecommendWrapper>
     <RecommendItem imgUrl="../../static/banner.png" >
     </RecommendItem>  
</RecommendWrapper>

export const RecommendItem = styled.div`
    width: 280px;
    height: 50px;
    background-size: contain;
    background: url(${(props)=>props.imgUrl});  
`;

enter image description here

if i use like this,it can work,but can't change image dynamic.

import banner from "../../statics/banner.png"
export const RecommendItem = styled.div`
    width: 280px;
    height: 50px;
    background-size: contain;
    background:url(${banner}); 
`;

and if i use a network image(url likes "https://syean.cn/img/avatar.jpg") ,it also can work

5 Answers

React, Gatsby and Next.js all generally use Webpack, which compiles your site before deployment. They will minify imagery and change each image's path.

In order to get images to load properly, you have to reference them dynamically as an import. This way, the variable URL will still work after Webpack does its thing.

import styled from 'styled-components';
import img from './img/bg.gif';
    
const Content = styled.div`
  border: 1px solid #000;
  background-image: url(${img});
  width: 2000px;
  height: 2000px;
`;

Move your file in public folder and try this command:

<RecommendItem imgUrl={process.env.PUBLIC_URL + '/banner.png'} >
import styled from 'styled-components';
// used as 
<Heading image={require('./images/headerBackground.jpg')} />

// a styled component
const Container = styled.div`` 
// the class made as
class Heading extends Component {
  render() {
    return (
      <Container image={this.props.backgroundimage}>
          <Logo />
          <Navigation />
          <HeadingBox />
      </Container>
    )
  }
}
export default Heading;

You may create next.config.js in project's root dir and add this code:

const webpack = (config, options) => {

  config.module.rules.push({
    test: /\.(png|jpe?g|gif)$/i,
    loader: 'file-loader',
    options: {
      // name: '[path][name].[ext]',

      name() {
        // `resourcePath` - `/absolute/path/to/file.js`
        // `resourceQuery` - `?foo=bar`

        if (process.env.NODE_ENV === 'development') {
          return '[path][name].[ext]';
        }

        return '[contenthash].[ext]';
      },
      publicPath: `/_next/static/images`,
      outputPath: 'static/images',
      limit: 1000,
    },
  });

  return config
}

module.exports = { webpack }

Do not forget install file-loader if not installed yet.

yarn add -D file-loader

Then in your component you may do like this:

const imgUrl = require("../../static/banner.png").default;

<RecommendItem imgUrl={imgUrl} >

Will be used abs url from bandles.

You should let the function in the background-image value return a string, url(your_image_link).

<RecommendWrapper>
     <RecommendItem imgUrl="img_link" >
     </RecommendItem>  
</RecommendWrapper>

export const RecommendItem = styled.div`
    width: 280px;
    height: 50px;
    background-size: contain;
    background: ${(props) => `url(${props.imgUrl})`}; 
Related