Code
Code Component
Code Overrides
Framer X

Text input: change text by clicking a button

Overview

Thanks Vitaly for requesting this tip.

The requirement is as simple as: change the text of an input by clicking a button/link. There’s actually a hidden requirement: the input must remain working, i.e. we should still be able to enter text into it.

Set the text of an input

To set the text of an input, we can assign its value prop to this.props.text:

class TextInput extends React.Component {
  ...
  render() {
    return (
      <input 
        type="text" 
        value={this.props.text} />
    )
  }

then override this prop:

export const TextInput: Override = () => {
  return {
    text: data.inputText,
  }
}

export const LearnReact: Override = () => {
  return {
    onTap() {
      data.inputText = "Learn React";
    }
  };
};

“Fix” the text input

The above works: if we assign the LearnReact override to a frame, we’ll be able to change the text of the input to “Learn React” when we click on it. However, we’ll soon notice that the text input becomes ready-only — no matter what key we press, the content of the text input does not change!

This is caused by this sucker:

<input 
  type="text" 
  value={this.props.text} />

It binds the value of the text input with the text prop and makes the input a controlled component. The only way to change the content is to give it a new prop.

We’ll do so in the TextInput code override:

export const TextInput: Override = () => {
  return {
    text: data.inputText,
    onChange(text) {
      data.inputText = text;
    },
  }
}

Remember to declare and process the onChange prop in the TextInput component, as discussed in this tip:

export class TextInput extends React.Component<Props> {
  ...
  handleChange = e => {
    const { onChange } = this.props;
    onChange && onChange(e.target.value);
  };

  render() {
    return (
      <Input
        type="text"
        onChange={this.handleChange}
        value={this.props.text}
      />
    );
  }
}

Note: you may be tempted to use internal state in the TextInput component to track the content of the input. Don’t! Better to store the state outside the TextInput as a “single source of truth” and pass the value into the component as a prop. In this case, we use the Code override to store the state (it’s in data.inputText).

PS: If you find this tip difficult to understand, check out this course I prepared for you, where concepts are explained in a more digestible way. No programming experience required!

PPS: See other pro tips, or share / request a new tip.


download Want the complete source file? Enter your email address below:

I'll also send you new tips when available. No spam, unsubscribe any time!


© 2018 jimu Labs, Inc.