Reputation: 789
i am following the usage with React Redux tutorial. Something I really don't get is how to retrieve user input.
They build a FilterLink container, whose mapDispatchToProps is
const mapDispatchToProps = (dispatch, ownProps) => {
return {
onClick: () => {
dispatch(setVisibilityFilter(ownProps.filter))
}
}
}
So it injects its ownProps.filter to the connected presentational component. If we go and see how this container is construced
const Footer = () => (
<p>
Show:{" "}
<FilterLink filter="SHOW_ALL">All</FilterLink>{", "}
<FilterLink filter="SHOW_ACTIVE">Active</FilterLink>{", "}
<FilterLink filter="SHOW_COMPLETED">Completed</FilterLink>
</p>
)
Ok, there is the "filter" property. That's clear.
Now I want to build a text filter on the same example. So first here is my presentational component
const TodoSearch = ({onSubmit}) => (
<form
onSubmit={e => {
e.preventDefault()
onSubmit()
}}
>
<input placeholder="Text search" />
<input type="submit" value="Go" />
</form>
)
But when I come to write the container I don't know how to get user input
const mapDispatchToProps = (dispatch) => {
return {
onSubmit: () => {
dispatch(setTextSearch(????))
}
}
}
It's something I would do with jQuery $(#text).val() but... is it the best way?
Later on on the same tutorial they build a little form to add a todo to the list. Ok, let's go and see how they catch input then.
let AddTodo = ({ dispatch }) => {
let input
return (
<div>
<form onSubmit={e => {
e.preventDefault()
if (!input.value.trim()) {
return
}
dispatch(addTodo(input.value))
input.value = ''
}}>
<input ref={node => {
input = node
}} />
<button type="submit">
Add Todo
</button>
</form>
</div>
)
}
Wait, where's the magic here? Did they inject value into "input" variabile with that ref trick? Is that correct? So if there were 20 input fields, have I to use 20 variables with 20 different refs?
Any help is appreciate, thank you
Upvotes: 8
Views: 11189
Reputation: 46
I use ref to get the value of input, the handleSubmit() method is in the class, so it can get input by ref. If you want use the dispatch method, just map some props in mapDispatchToProps().
class AddTodo extends Component {
handleSubmit(event) {
let input = this.refs.input;
event.preventDefault();
if (!input.value.trim()) {
return
}
this.props.addTodo(input.value);
input.value = ''
}
render() {
return (
<div>
<form onSubmit={this.handleSubmit.bind(this)}>
<input ref="input"/>
<button type="submit">
Add Todo
</button>
</form>
</div>
);
}
}
const mapDispatchToProps = (dispatch, ownProps) => {
return {
addTodo:(text) => {
dispatch(addTodo(text));
}
}
};
export default connect(null, mapDispatchToProps)(AddTodo);
Upvotes: 2
Reputation: 756
Change your submit function to the following.
const mapDispatchToProps = (dispatch) => {
return {
onSubmit: (evt) => {
dispatch(setTextSearch(evt.target.querySelector('input').value)
}
}
}
Also,
const TodoSearch = ({onSubmit}) => (
<form
onSubmit={e => {
e.preventDefault()
onSubmit(e)
}}
>
<input placeholder="Text search" />
<input type="submit" value="Go" />
</form>
)
Upvotes: 3
Reputation: 1627
If you want to get the users input, you can do something like this:
This demo SearchForm
component renders an input field and a button to trigger the action.
import React, { Component, PropTypes } from 'react'
export default class SearchForm extends Component {
constructor(props) {
super(props)
this.handleGoClick = this.handleGoClick.bind(this)
}
getInputValue() {
return this.refs.input.value
}
handleGoClick() {
this.props.onChange(this.getInputValue())
}
render() {
return (
<div>
<input ref='input' />
<button onClick={this.handleGoClick}>Go</button>
</div>
)
}
}
Notice that the input field has a ref value. You can retrieve the current value with this.refs.input.value
. The handleGoClick
method then passes this value to an action creator (that was passed into the props of the component via mapDispatchToProps).
Upvotes: 3
Reputation: 8686
This example is here to let you better understand the react-redux way of doing things typical to react-redux, such as connect a component. It's not a tutorial to learn how to manage input state.
So, for the sake of example, they use the ref
attribute to assign to the input
variable the <input/>
DOM node . Then, the value of this input DOM node is accessible via input.value
.
They use what is called a Uncontrolled Component, i.e a component that handle its state internally. It's handy when you don't have to deal with complex form and when the value of this particular component is not intended to be used elsewhere.
But, let's say now that this todo item text need to be saved to the server for example. The value of this input is now intended to be used elsewhere, in this case, probably in an action creator that handles the POST request. In this case, the value of the form is contained in your redux store, and you're now dealing with Controlled Component
Upvotes: 0