Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React: Add/Change text input base on a selected option

I am trying to display a new text input based on the selected option. I am able to do that as below but the old value entered is always present no matter what I change the new select option to.

What might be a better way to achieve this? Appreciate any suggestions.

class loadComponent extends React.Component {
    static propTypes = {
      ......
    };
    static defaultProps = {
     ....
    };
    constructor() {
     super();
     this.state = {
       value: ""
     };
    }
     state = {
      ...
     };

reset = (selected) => {
       this.setState({
        selectedInputName: selected.target[selected.target.selectedIndex].text,
        selectedInputId: selected.target.value
       });
};

makeTextInput = () => {
    return (
        <TextInput
            label={this.state.selectedInputName}
            placeholder={`Please enter ${this.state.selectedInputName} here!`}
            onBlur={event => this.setState({[this.state.selectedInputId]: event.target.value})}
            showClear
            value={this.state.value}
        />
    );
};
render() {
    let newInputText = '';
    if (this.state.selectedInputId !== '') {
        newInputText = this.makeTextInput();
    }
    return (
        <Select
            label="What would you like to search with?"
            options={this.props.searchOptions}
            onChange={selected => this.reset(selected)}
        />
        <div className="search margin_bottom_large">
            {newInputText}
    );
like image 968
oyeesh Avatar asked Mar 14 '26 05:03

oyeesh


2 Answers

makeTextInput function creates a new object, but from react's perspective it's the same component because react distinguishes them by looking at their type and key. To make react recreate an element, you have to change one of those values.

This code changes type of NewInputText element each time it renders (because NewInputText always refers to a new function):

reset = (selected) => {
       this.setState({
        selectedInputName: selected.target[selected.target.selectedIndex].text,
        selectedInputId: selected.target.value
       });
};

makeTextInput = () => {
    return (
        <TextInput
            label={this.state.selectedInputName}
            placeholder={`Please enter ${this.state.selectedInputName} here!`}
            onBlur={event => this.setState({[this.state.selectedInputId]: event.target.value})}
            showClear
        />
    );
};
render() {
    let NewInputText = () => '';
    if (this.state.selectedInputId !== '') {
        NewInputText = () => this.makeTextInput();
    }
    return (
        <Select
            label="What would you like to search with?"
            options={this.props.searchOptions}
            onChange={selected => this.reset(selected)}
        />
        <div className="search margin_bottom_large">
            <NewInputText />
    );

This code assigns different key to TextInput each time:

reset = (selected) => {
       this.setState({
        selectedInputName: selected.target[selected.target.selectedIndex].text,
        selectedInputId: selected.target.value
       });
};

makeTextInput = () => {
    return (
        <TextInput
            key={Math.random()}
            label={this.state.selectedInputName}
            placeholder={`Please enter ${this.state.selectedInputName} here!`}
            onBlur={event => this.setState({[this.state.selectedInputId]: event.target.value})}
            showClear
        />
    );
};
render() {
    let newInputText = '';
    if (this.state.selectedInputId !== '') {
        newInputText = this.makeTextInput();
    }
    return (
        <Select
            label="What would you like to search with?"
            options={this.props.searchOptions}
            onChange={selected => this.reset(selected)}
        />
        <div className="search margin_bottom_large">
            {newInputText}
    );
like image 166
marzelin Avatar answered Mar 15 '26 20:03

marzelin


Is there a better way to do this?

I think using the controlled component design pattern would be ideal in this situation.

class SomeInput extends Component {
    constructor() {
        super();

        this.state = {
            value: "" //Keep value state here
        };
    }

    render() {
        /* Doing something like the following will allow you to clear
           the input value simply by doing the following..

           this.setState({ value: '' });
        */
        return (
            <Input
                type="text"
                onChange={e => this.setState({ value: e.target.value })} // set value state to entered text
                value={this.state.value} // set value of input to value piece of state
            />
        );
    }
}

This will give you full access to the current value of the input, thereby allowing you to set it to anything or clear it at anytime or for any event simply by doing the following this.setState({ value: '' }).

like image 39
canaan seaton Avatar answered Mar 15 '26 19:03

canaan seaton



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!