最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - React: AddChange text input base on a selected option - Stack Overflow

programmeradmin0浏览0评论

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}
    );

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}
    );
Share Improve this question edited Aug 14, 2017 at 17:53 oyeesh asked Aug 14, 2017 at 15:09 oyeeshoyeesh 58110 silver badges29 bronze badges 3
  • so basically you want to clear the current input from the user when the input type is changed? – canaan seaton Commented Aug 14, 2017 at 15:19
  • @canaanseaton Yeah, Thats exactly what I am trying to achieve. – oyeesh Commented Aug 14, 2017 at 15:30
  • okay, see my solution below. Doing something of that sort will allow you to reset the value of the input anytime you want, say when an input type changes. – canaan seaton Commented Aug 14, 2017 at 15:31
Add a ment  | 

3 Answers 3

Reset to default 3

makeTextInput function creates a new object, but from react's perspective it's the same ponent 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}
    );

Is there a better way to do this?

I think using the controlled ponent 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: '' }).

Don't know the rest of your code which could be handy but you can try:

makeTextInput = () => (
        <TextInput
          label={this.state.selectedInputName}
          placeholder={`Please enter ${this.state.selectedInputName} here!`}
          onBlur={event => this.setState({[this.state.selectedInputId]: event.target.value})}
          showClear
        />
      );

change = (event) => {
     this.setState({
       selectedInputName: event.target.value
     });
 }   

render() {
      return (
          <Select
            label="What would you like to search with?"
            options={this.props.searchOptions}
            onChange={this.change}
          />
          <div className="search margin_bottom_large">
          {this.makeTextInput()}
       );

What you need to do is only setState properly. Each time you change a state the ponent will be re-rendered which means that the makeTextInput method will be triggered.

EDIT:

by the way, it is good idea to use getter for returning ponent in render method, in this case:

get textInput() { 
    return (
       <TextInput
         label={this.state.selectedInputName}
         placeholder={`Please enter ${this.state.selectedInputName} here!`}
         onBlur={event => this.setState({[this.state.selectedInputId]: event.target.value})}
         showClear
       />
    );

}

and then in render method, just use {this.textInput}

发布评论

评论列表(0)

  1. 暂无评论