1

I'm relative new to react and I need to create a character counter component (CharacterCounter) for a input field.

enter image description here

This question is not specific to this component (character counter) - but is a generic question about components best practices in general.

I can implement in two ways (as far I know - if there are better ways I'm happy to hear about it):

1) Wrapping the component and have the input field as a child - The component will insert the span (for showing the counter) after the input field

<CharacterCounter maxLength={50}>
    <input type="text">
  </CharacterCounter>

and

const input = this.container.firstChild
input.addEventListener('keyup', function() { ... });
  • advantage: I can have multiple components for the same input - if I need extra functionality (components) for this input.
  • disadvantage: If the input for some reason stop being the first child of this component - stop working/ fragile

2) To create a generic component which will render the input and the counter on the render() function

like:

<CharacterCounter />

render() {
    return (
        <input type="text">
        <span>{this.state.count}</span>
    )
  • advantage: Not fragile - not relying on the first child
  • disadvantage: Not sure is possible to have other component for the same input - let's say I need another component for tracking every time the user type/ or focus/ or blur the field

What is the best practices?

2 Answers 2

1

Surely the second approach is better as it is not directly interfering with DOM elements.

If you wanted to have access to DOM elements, still it's better to use refs.

disadvantage: Not sure is possible to have other component for the same input - let's say I need another component for tracking every time the user type/ or focus/ or blur the field

You will get around that easily just with props.

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

Comments

0

You could use second approach with components with state and then use composition to extend that component or create more “special cases” of that component.

let {Component} = React;

class Input extends Component {
  constructor(props) {
    super(props);
    this.state = {count: 0}
  }
  
  render() {
    return <div>
      <input 
      {...this.props}
      onChange={() => {
        let count = this.refs.inputCount.value.length;
        this.setState({count})
      }}
      type="text" 
      maxLength="50"
      ref="inputCount" />
      <span> {this.state.count} / 50</span>
    </div>
  }
}

class FocusInput extends Component {
  render() {
    return <Input 
    onFocus={() => {
      console.log('Focus')
    }} />
  }
}

class App extends Component {
  render() {
    return <div>
      <Input />
      <FocusInput />
    </div>
  }
}

ReactDOM.render(
  <App />,
  document.getElementById('app')
);
<script src="https://unpkg.com/[email protected]/umd/react.development.js"></script>
<script src="https://unpkg.com/[email protected]/umd/react-dom.development.js"></script>
<div id="app"></div>

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.