0

I am very new to React and so I wonder sometimes when I got something working if I did it the "correct" way.

I wrote a simple TimePickerComponent(based on material-ui-next):

class TimePickerComponent extends React.Component {
    _placeholder;
    _defaultTimeString;
    _timeString;
    _errorStatus;
    _classes;

    constructor({ placeholder, defaultTimeString, timeString, errorStatus, classes }) {
        super();
        this._placeholder = placeholder;
        this._defaultTimeString = defaultTimeString;
        this._timeString = timeString;
        this._errorStatus = errorStatus;
        this._classes = classes;
    }

    get Placeholder() {
        return this._placeholder;
    }

    get DefaultTimeString() {
        return this._defaultTimeString ? this._defaultTimeString : CONTROLS_CONSTANTS.DEFAULT_TIME_STRING;
    }

    get TimeString() {
        return this._timeString;
    }

    get ErrorStatus() {
        return this._errorStatus;
    }

    get Classes() {
        return this._classes;
    }

    render() {
        return <FormControl>
            <TextField error={this.ErrorStatus}
                label={this.Placeholder}
                defaultValue={this.TimeString ? this.TimeString : this.DefaultTimeString}
                className={this.Classes.layout}
                type="time"
                InputLabelProps={{
                    shrink: true
                }}
            />
        </FormControl>
    }
}

TimePickerComponent.propTypes = {
    placeholder: PropTypes.string.isRequired,
    defaultTimeString: PropTypes.string,
    timeString: PropTypes.string,
    errorStatus: PropTypes.bool
}

export default withStyles(styles)(TimePickerComponent);

As you see I created "private" fields (I know that they are not private in this case) and in the constructor, I assign the values I got as props to these fields.

And the getters just return the private fields or include some logic like the DefaultTimeString getter.

My question now: Is this the or a correct way? Or will I have problems with this? For me, it is very straightforward and self-explaining.

Thank you in advance.

6
  • 2
    Your question is subjective to the education/experience and consequent preferences of each programmer :). There's nothing firmly wrong in your approach. Commented Nov 29, 2017 at 17:25
  • Thats nice to hear, thank you. I was a litte bit suspicious because of assigning the values in the constructor because there a life cycle hooks from react where I could do these also. And the first answer says also I should put it in the componentWillMount hook. Commented Nov 29, 2017 at 17:44
  • Your approach is a bit verbose in the sense that you don't really need a constructor for this particular code snippet. You can access all your values via props. A simple stateless presentational component can do everything this snippet does in 10 lines of code. const TimePickerComponent = ({ placeholder, defaultTimeString, timeString, errorStatus, classes }) => /* JSX from render() */. But this assumes that the component is only used to present information in a certain way and not perform any logic. Commented Nov 29, 2017 at 18:02
  • Yes, I know this syntax and I used it before for this component. But now I need some logic and because of that, I refactored it. Commented Nov 29, 2017 at 18:20
  • Of course, hence the last sentence in my comment :). My first comment still stands. Besides being a bit obvious you have some Java background, there's nothing wrong with your approach :P Commented Nov 29, 2017 at 18:31

2 Answers 2

1

You need to use PropTypes and internal State. Assigning values at construct is not a good practice as you should use the componentWillMount method from the React Lifecycle for better control over those values.

Those recommendations are there so you keep your code structured and taking advantage of React Components internals. Of course, you can bypass it and fallback to pure javascript if you know what you're doing.

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

1 Comment

I edit my post because I have PropTypes(except you mean something different). I want to use Redux later so I won't have internal state in my components. Thank you, I will move it to the componentWillMount method then.
1

You could use ES6's destructing feature for props. Recommended way to do it would be:

class TimePickerComponent extends React.Component {

 constructor(props) {
    super(props);
 }

 //All the other functions go in here.

 render (){
  const {
    placeholder, 
    defaultTimeString, 
    timeString, 
    errorStatus, 
    classes
   } = this.props

  return (
   <FormControl>
     <TextField error={errorStatus}
        label={placeholder}
        defaultValue={timeString? this.TimeString: defaultTimeString}
        className={classes.layout}
        type="time"
        InputLabelProps={{ shrink: true }}
        />
    </FormControl>);
  }
}

If you what to assign props to local state of the component you could do something like this in the constructor.

 this.state = { 
   placeholder : props.placeholder,
   defaultTimeString : props.defaultTimeString
 }

Hope this helps.

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.