0

I have a Clock component where the divs represent the clock's hands. The hours, minutes, and seconds should rotate to a certain degree amount, when updated to the current time.

updateClockHandsToCurrentTimeHandler is called every second by setInterval when the component is mounted.

import React, {Component} from 'react';
import ReactDOM from 'react-dom';

const clock = {
    width: '20rem',
    height: '20rem',
    borderStyle: 'solid',
    borderRadius: '50%'
}

const x = '100'
const clockFace = {
    width: '100%',
    height: '100%',
    transform: `translate(${x}px)`
}
const hours = {
    position: 'absolute',
    top: '50%',
    width: '50%',
    height: '6px',
    transformOrigin: '100%',
    transform: [{ rotate: '90deg'}],
    background: 'linear-gradient(to right, rgba(255, 0, 0, 0) 0%, rgba(255, 0, 0, 0) 30% black 30%, black 30%, black 100%)'
}

const minutes = {
    position: 'absolute',
    top: '50%',
    width: '50%',
    height: '6px',
    transformOrigin: '100%',
    transform: [{ rotate: '90deg'}],
    background: 'linear-gradient(to right, rgba(255, 0, 0, 0) 0%, rgba(255, 0, 0, 0) 10% black 30%, black 10%, black 100%)'
}

const seconds = {
    position: 'absolute',
    top: '50%',
    width: '50%',
    height: '6px',
    transformOrigin: '100%',
    transform: [{ rotate: '90deg'}],
    background: 'linear-gradient(to right, rgba(255, 0, 0, 0) 0%, rgba(255, 0, 0, 0) 10% black 30%, black 10%, black 100%)'
}

class Clock extends Component {
    constructor(props) {
    super(props);
        this.secondsElement = React.createRef('.seconds');
        this.minutesElement = React.createRef('.minutes');
        this.hoursElement = React.createRef('.hours');
    }

    componentDidMount() {
        setInterval(this.updateClockHandsToCurrentTimeHandler, 1000);
        this.updateClockHandsToCurrentTimeHandler();
  }

    updateClockHandsToCurrentTimeHandler = () => {
        // get the current time
        const now = new Date();

        // break it down to hours, minutes and seconds
        const seconds = now.getSeconds();
        const minutes = now.getMinutes();
        const hours = now.getHours();

        // calculate the rotation of each clock hand in degrees
        const secondsRotationDegrees = (seconds / 60) * 360; // (60/60) * 360
        const minutesRotationDegrees = (minutes / 60) * 360 + (seconds/60) * 6; // ((60/60) * 360) + ((60/60) * 6 )
        const hoursRotationDegrees = (hours/ 12) * 360 + (minutes / 60) * 30;

        this.secondsElement.transform = `rotate(${secondsRotationDegrees+90}deg)`;
        this.minutesElement.transform = `rotate(${minutesRotationDegrees+90}deg)`;
        this.hoursElement.transform = `rotate(${hoursRotationDegrees+90}deg)`;
    }

    render() {
        return (
            <div style={clock}>
                <div style={clockFace}>
                    <div style={hours}></div>
                    <div style={minutes}></div>
                    <div style={seconds}></div>
                </div>
            </div>
        );
    }
}

ReactDOM.render(<Clock />, document.getElementById('root'));

With my current code, I receive the TypeError pointing to this line this.secondsElement.transform = rotate(${secondsRotationDegrees+90}deg). Any suggestions on how to accomplish the task? Thank you.

1 Answer 1

1
  • Firstly you need to associate the refs to your div elements.
  • Secondly, to access the element you need to use .current.
  • Finally to apply styles to refs you need to use .current.style.transform

Like this:

updateClockHandsToCurrentTimeHandler = () => {
        // get the current time
        const now = new Date();

        // break it down to hours, minutes and seconds
        const seconds = now.getSeconds();
        const minutes = now.getMinutes();
        const hours = now.getHours();

        // calculate the rotation of each clock hand in degrees
        const secondsRotationDegrees = (seconds / 60) * 360; // (60/60) * 360
        const minutesRotationDegrees = (minutes / 60) * 360 + (seconds/60) * 6; // ((60/60) * 360) + ((60/60) * 6 )
        const hoursRotationDegrees = (hours/ 12) * 360 + (minutes / 60) * 30;

        this.secondsElement.current.style.transform = `rotate(${secondsRotationDegrees+90}deg)`;
        this.minutesElement.current.style.transform = `rotate(${minutesRotationDegrees+90}deg)`;
        this.hoursElement.current.style.transform = `rotate(${hoursRotationDegrees+90}deg)`;
    }

    render() {
        return (
            <div style={clock}>
                <div style={clockFace}>
                    <div ref={hoursElement} style={hours}></div>
                    <div ref={minutesElement} style={minutes}></div>
                    <div ref={secondsElement} style={seconds}></div>
                </div>
            </div>
Sign up to request clarification or add additional context in comments.

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.