Search code examples
reactjsstyled-components

Is it possible to add a state to a styled react component like this?


import React from "react"
import styled from 'styled-components';

const Segment = styled.div`
    background-color: #1070ff;
    box-sizing: border-box;
    border-bottom: 6px solid #ffffff33;
    width: 400px;
    height: 70px;
    &:first-of-type {
        background-color: red !important;
    }
    &:last-child {
        border-radius: 0px 0px 35px 35px;
    }
`

export default Segment;

I know I can create functions in this file, but is it possible to have a state for Segment while it's a styled component, or would I have to make it into a class?

Basically I just plan on adding a handleClick method to change the bgColor but I'm unsure if I have to restructure the component to be able to add state.

How would I achieve this?


Solution

  • A state cannot be added to a styled component only props can be passed. But a styled component can be used inside any other class-based or functional component. What you would do is pass the color as prop to a styled component from a React Component and then you can export the React Component as follows:

    // If a color has been passed from props use that, if not use a default color value
    const Segment = window.styled.div`
    	background-color: ${props => (props.color ? props.color : "#1070ff")};
    	box-sizing: border-box;
    	border-bottom: 6px solid #ffffff33;
    	width: 400px;
    	height: 70px;
    `
    
    class SegmentClass extends React.Component {
    	state = { color: "#000" }
    
    	// If the color is black change to blue otherwise change to black
    	changeColor = () => {
    		this.setState((state, props) => {
    			const { color } = state
    			const newColor = color === "#000" ? "#1070ff" : "#000"
    			return { color: newColor }
    		})
    	}
    
    	render() {
    		return <Segment color={this.state.color} onClick={this.changeColor} />
    	}
    }
    
    ReactDOM.render(<SegmentClass />, document.getElementById("app"))
    <script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
    <script src="https://unpkg.com/styled-components/dist/styled-components.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
    <div id="app"></div>

    Now you can export the SegmentClass which will provide the required functionality