1

I started learning React approx. month ago and I'm very confused about the concept because its still something new to me(compared to my previous work in C++ and C).

To quickly summarize I would like to know what is React's equivalent of C++ return form a function. How would I return value(or values) from a function(in my case class functions/states) and use it in my other components.

I have made an simple script that changes background to simulate RGB light on mouse and I made it so the HSL color mode is applied to the background of the component. I would like to use this on multiple components,icons, etc on my page but it feels like there is a better way than importing all functions in three files making the work triple than requiered.

import React, { Component } from 'react'
import './colorStrip.scss'


class ColorStrip extends Component {

    constructor(props) {
        super(props)

        this.colorHue=10;
        this.colorSaturation=100;
        this.colorLightness=50;

        this.state = {
            color:"hsl(0,100%,50%)"
        }

        this.changeColor(1);
    } 


    changeColor = (speed) => {

        this.colorHue+=10*speed;

        if(this.colorHue>=360)
            this.colorHue=0;

        this.setState({ 
            color : "hsl("+this.colorHue+","+this.colorSaturation+"%,"+this.colorLightness+"%)"
        })


        setTimeout(() => {this.changeColor(speed)},75)
    }



    render() {
        return (
            <svg style={{backgroundColor:this.state.color}} className="strip">
            </svg>

        )
    }
}

export default ColorStrip

So I would like to use this.state.color(or this.state.colorHue or any state) in three other SVG components on my page.

I really looked some of the other answers but they were quite complex and requiered multiple returns which was confusing.

1
  • If you want to use the same values on all components, you can use Context for that. Commented Jun 24, 2019 at 0:09

4 Answers 4

2

There are a couple different options you can use to achieve this. One would be to move your function that calculates the colour to a higher level component (so one of the parent components), that has the child components you want to pass this state to, and then pass your state down through component props.

class parent extends component {
    // your functions to calculate your colour

    render () {
        return <div>
            <ChildComponent colourProp={this.state.color} />
            <ChildComponent colourProp={this.state.color} />
            <ChildComponent colourProp={this.state.color} />
        </div>
    }
}

Another option if you need the colour to change based on the child component, is to pass down the function that alters the colour to the child component. So similar to the example above, but you would pass down the colour changing function to the child as well.

<ChildComponent colourProp={this.state.color} changeColour={this.changeColourFunction}/>

Now you can call that function from your child

// Inside child component
this.props.changeColour(params)

And now your parent will change its state, and the new colour will get changed in the parent and passed down to all the children.

Lastly you can try using ReactContext, set it up in a file that's external to all your components and and import it to your components. In your parent component where you pass your initial state, you would use YourContext.Provider and pass your initial state. Then in your children you can use YourContext.Consumer. For more details on this see : https://reactjs.org/docs/context.html

Sign up to request clarification or add additional context in comments.

Comments

1

As Jonathan said, you can pass state as props to other components, but only if they are connected. If the svgs you are using are not being rendered in the same file, things will become a little messy. In order to 'fix' this, people use state management tools, such as redux and context API.

Redux, for example, is built based on database design, so you can access the state globally. Tough it is really useful, the environment is not beginners friendly, and I do not advise you learning it until completely grasping react.

2 Comments

This is a great point for general state management, but in practice, you would want to avoid using Redux for basic state management such as style changes. You should generally generally use redux for app/ webpsite wide data flow and avoid using it as a solution for smaller state changes such as style here. If the nesting of these components are complicated, and the svgs are deeply nested, using the context API would be the best option. Redux should be used as a last resort in this scenario! :)
Yes! Because I haven't use context api, I explained what state management is using redux, but its really not advisable to use it in there. Context api would be a better solution
0

Try this way:

import './colorStrip.scss'
class ColorStrip extends Component {
  constructor(props) {
    super(props)
    this.colorHue=10;
    this.colorSaturation=100;
    this.colorLightness=50;
    this.state = {
        color:"hsl(0,100%,50%)"
    }
    this.changeColor(1);
  } 
  changeColor = (speed) => {
    this.colorHue+=10*speed;
    if(this.colorHue>=360)
        this.colorHue=0;
    this.setState({ 
        color : "hsl("+this.colorHue+","+this.colorSaturation+"%,"+this.colorLightness+"%)"
    })
    setTimeout(() => {this.changeColor(speed)},75)
  }
  render() {
  const { color } = this.props;
    return (
        <svg style={backgroundColor:color} className="strip">
        </svg>
    )
  }
}
export default ColorStrip

Comments

0

I'd suggest creating a Higher-Order Component (HOC) to house the color logic and then you can wrap any component you want with this HOC and the wrapped component will have the logic & data you need.

For example:

import React, { Component } from "react";

function withColor(WrappedComponent) {
    return class ComponentWithColor extends Component {
        constructor(props) {
            super(props);

            this.colorHue=10;
            this.colorSaturation=100;
            this.colorLightness=50;

            this.state = {
                color:"hsl(0,100%,50%)"
            }

            this.changeColor(1);
        }

        changeColor = (speed) => {

            this.colorHue+=10*speed;

            if(this.colorHue>=360)
                this.colorHue=0;

            this.setState({ 
                color : "hsl("+this.colorHue+","+this.colorSaturation+"%,"+this.colorLightness+"%)"
            })


            setTimeout(() => {this.changeColor(speed)},75)
        }

        render() {
            const { color } = this.state;
            return <WrappedComponent color={ color } { ...this.props }/>
        }
    }
}

Then if you define a new component, and you want it to have access to the color prop, just wrap the component class/function in withColor before constructing.

For example:

class MyComponent extends Component {
    render() {
        const { color } = this.props;

        return (
            <svg style={backgroundColor:color} className="strip">
            </svg>
        )
    }
}

const MyComponentWithColor = withColor(MyComponent);
// then export & use MyComponentWithColor

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.