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 ponent. 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 ponent
const TodoSearch = ({onSubmit}) => (
<form
onSubmit={e => {
e.preventDefault()
onSubmit()
}}
>
<input placeholder="Text search" />
<input type="submit" value="Go" />
</form>
)
But when I e 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
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 ponent. 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 ponent
const TodoSearch = ({onSubmit}) => (
<form
onSubmit={e => {
e.preventDefault()
onSubmit()
}}
>
<input placeholder="Text search" />
<input type="submit" value="Go" />
</form>
)
But when I e 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
Share Improve this question asked Jul 9, 2016 at 12:47 MarcoMarco 7893 gold badges9 silver badges23 bronze badges 1- I believe it's a problem of react, rather than redux. And it's well explained in reactjs/docs/forms.html#controlled-ponents. – Walty Yeung Commented Oct 2, 2017 at 7:39
4 Answers
Reset to default 3Change 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>
)
If you want to get the users input, you can do something like this:
This demo SearchForm
ponent 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 ponent via mapDispatchToProps).
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);
This example is here to let you better understand the react-redux way of doing things typical to react-redux, such as connect a ponent. 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 ponent that handle its state internally. It's handy when you don't have to deal with plex form and when the value of this particular ponent 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