Reputation: 13108
I'm trying to manually clear the value of an input in ReactJS. Right now I have it setup so that updating the field's value updates the state of the parent app, and the state of the parent app resets on pressing the "Enter" key, but I can't get the input to clear its value to match the parent app's state.
I'm just starting out, so I'm sure there are a lot of problems with my code. Thanks for any help you can offer.
class AddNote extends Component {
componentWillUpdate() {
console.log(store.getState().searchHandler.searchTerm);
this.state = {searchTerm: store.getState().searchHandler.searchTerm};
}
constructor() {
super();
this.state = {
searchTerm: undefined
}
}
render() {
const {
onAddClick,
onSearchUpdate,
searchHandler,
} = this.props;
let searchTermInput;
return (
<div>
<input
ref={node => {
searchTermInput = node;
}}
value={this.state.searchTerm}
onChange={this.props.onChange.bind(this)}
onKeyPress={(e) => {
let searchTermToPass = searchTermInput.value;
onAddClick(e, searchTermToPass);
}}
/>
</div>
);
}
class RecollectApp extends Component {
componentWillUpdate() {
console.log("We're updating!");
}
render() {
const {
notes,
searchHandler,
} = this.props;
return (
<div>
<AddNote
onAddClick={(e, searchTerm) => {
if (e.charCode === 13) {
store.dispatch({
type: 'ADD_NOTE',
id: nextNoteID++,
title: searchTerm,
});
store.dispatch({
type: 'RESET_STATE',
});
}
}
}
onChange={(e) => {
store.dispatch({
type: 'UPDATE_STATE',
searchTerm: e.target.value,
});
this.value = "";
}}
/>
<NoteList
notes={notes}
onNoteClick={id =>
store.dispatch({
type: 'SELECT_NOTE',
id,
})
}
/>
</div>
);
}
}
Upvotes: 0
Views: 204
Reputation: 7026
Your problem is that you don't forcing rerender in AddNote
component after state is changed. Instead of setting state directly, you should use setState
method:
class AddNote extends Component {
componentWillUpdate() {
this.setState({
searchTerm: store.getState().searchHandler.searchTerm,
});
}
// Other methods...
}
As I understand, you don't need to use input value
from AddNote
component elsewhere.
So you don't need to store it in redux state.
According this, your AddNote
component can be implemented like this:
// We need to install additional npm module, for serializing form data.
import serialize from 'form-serialize';
// As you don't need local state, you can implement component as pure function.
function AddNote({ onSubmit }) {
let input;
function handleSubmit(e) {
// Preventing default form behavior.
e.preventDefault();
// Serializing formData to javascript object.
const formData = serialize(e.target, {
hash: true
});
// Resetting input value.
input.value = '';
onSubmit(formData.title);
}
// We are using `onSubmit` prop of form element, to add note, instead of determining `enter` keycode.
return (
<form onSubmit={handleSubmit}>
<input type="text" name="title" ref={node => input = node} />
</form>
);
}
class RecollectApp extends Component {
render() {
const { notes } = this.props;
return (
<div>
{
// Here we are simply dispatching `value` given from `onSbumit` callback.
}
<AddNote
onSubmit={value => store.dispatch({
type: 'ADD_NOTE',
// Note, from your provided code `nexNoteID` is undefined.
id: nextNoteID++,
title: value,
})}
/>
<NoteList
notes={notes}
onNoteClick={id =>
store.dispatch({
type: 'SELECT_NOTE',
id,
})
}
/>
</div>
);
}
};
Upvotes: 1
Reputation: 21846
The onChange of input in AddNote component should be:
handleChange(e) {
this.setState({ searchTerm: e.target.value });
this.props.onChange(e, e.target.value);
}
Upvotes: 0