6

The issue I am having is after entering text for the first time, I then click Add and the input text box gets cleared. However when I start to enter text in again, the input text will not let me enter any text apart from the first letter. I'm not sure why it's doing this.

var FormTextBox = React.createClass({
    handleOnBlur: function (e) {
        this.props.onBlur(e.target.value);
    },
    render: function () {
        return (
            <input value={this.props.value} key={this.props.fid} type="text" onBlur={this.handleOnBlur} />
        )
    }
});

var TestFormTextBox = React.createClass({
    getInitialState: function (e) {
        return {
            value: ''
        }
    },
    handleOnAdd: function (e) {
        this.setState({ value: '' });
    },
    handleTextInfo: function (value) {
        this.setState({ value: value });
    },
    render: function () {
        return (
                <div>
                    <table>
                        <tbody>
                            <tr>
                                <td>Details</td>
                                <td></td>
                            </tr>
                            <tr>
                                <td><FormTextBox value={this.state.value} fid={1} onBlur={this.handleTextInfo} /></td>
                                <td><button onClick={this.handleOnAdd}>Add</button></td>
                            </tr>
                        </tbody>
                    </table>
                </div>
        )
    }
});

3 Answers 3

4

I am surprised that this even works the first time. With controlled components in react (ones where you are setting the value like you are with your input). you need to update the value whenever the user changes the text (with the onChange() event).

I made a JS fiddle here with your original code and you can see you can't even update the value in the input. In order to get it to update you need to replace the onBlur event with an onChange event like this JS fiddle. Hope that helps!

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

2 Comments

Is there anyway to use the defaultValue method? Updating the state after each character hit feels somewhat unpolished. I used onBlur so that it would only update state after they exit the textbox.
Don't worry, that is the way that React is built, it is done this way so that the state of your UI will always closely match the state of your UI model and it is actually quite fast due to how react handles UI changes! That being said are you doing a network request on every change of value? if so there are other ways to make that more efficient.
1

As mentioned here (https://facebook.github.io/react/docs/forms.html#controlled-components),

A controlled has a value prop. Rendering a controlled will reflect the value of the value prop.

User input will have no effect on the rendered element because React has declared the value to be Hello!. To update the value in response to user input, you could use the onChange event

You need to either change onBlur to onChange, or use defaultValue instead of value. e.g.

<input defaultValue={this.props.value} key={this.props.fid} type="text" onBlur={this.handleOnBlur} />

1 Comment

I tried the defaultValue but that doesn't work. If I do a console.log(this.props.value) in the render function before return ( <input defaultValue={this.props.value} .... ) nothing happens. The console.log is showing a blank value but the input is not clearing.
1

You need to change the value of the state variable as soon as you are typing the input value because that is what you are providing the input if you don't change it then the input wont show the updated value. In order to do this you need to use the onChange event everywhere.

var FormTextBox = React.createClass({
    handleOnChange: function (e) {
        this.props.onChange(e.target.value);
    },
    render: function () {
        return (
            <input value={this.props.value} key={this.props.fid} type="text" onChange={this.handleOnChange} />
        )
    }
});

var TestFormTextBox = React.createClass({
    getInitialState: function (e) {
        return {
            value: ''
        }
    },
    handleOnAdd: function (e) {
        this.setState({ value: '' });
    },
    handleTextInfo: function (value) {
        this.setState({ value: value });
    },
    render: function () {
        return (
                <div>
                    <table>
                        <tbody>
                            <tr>
                                <td>Details</td>
                                <td></td>
                            </tr>
                            <tr>
                                <td><FormTextBox value={this.state.value} fid={1} onChange={this.handleTextInfo} /></td>
                                <td><button onClick={this.handleOnAdd}>Add</button></td>
                            </tr>
                        </tbody>
                    </table>
                </div>
        )
    }
});

ReactDOM.render(<TestFormTextBox />, document.getElementById('app'));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react-dom.min.js"></script>
<div id="app"></div>

2 Comments

Is there a way without using onChange? I don't want to keep updating the state each time a character is entered, I want to update the state after the exit the textbox, and then clear on the add button.
Well if you are using state as a value then I you need to use onChange or try an eliminate the use of state as a value. I have'nt tried that before I this approach if not bad at all.

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.