2
\$\begingroup\$

i have some issues dealing with a simple case in my redux-react app: i want to reset an input text after an asynchronous operation ignited by a button.

Let’s say we have an input text in which you put a text and this is passed through a onClick event to a dispatch action. This action contacts a server and after the server response i want to reset the input field.

I’ve implemented a number of solutions (i’m using redux thunk) to this problem but i’m not sure if they are hacky ways to solve it, let me show you:

1) Presentational component (the input field) implements a reset method that is passed as a value to the onClick method.

export default React.createClass({

  reset: function () {
    this.setState({searchText: ''})
  },

  getInitialState: function () {
    return {
      searchText: ''
    }
  },

  render: function () {
    return (
        <div>
          <TextField
            value={this.state.searchText}
            onChange={e => this.setState({ searchText: e.target.value })}
          />
          <RaisedButton
            onClick={this.props.startSearch.bind(null,
              this.state.searchText,
              this.reset)} // ===> HERE THE RESET FUNCTION IS PASSED
          />
        </div>
    )
  }
})

The container dispatches the action and then calls the reset method.

const mapDispatchToProps = (dispatch) => {
  return {
    startSearch: (searchText, reset) => {
      dispatch(actions.startSearch(searchText))
      .then(() => reset())
    }
  }
}

2) Using ref (https://facebook.github.io/react/docs/refs-and-the-dom.html)

The container gets a reference to its child and calls reset through it

const SearchUserContainer = React.createClass({

  startSearch: (searchText) => {
    dispatch(actions.startSearch(searchText))
    .then(() => this.child.reset())
  },

  render: function () {
    return (
      <SearchUser {...this.props} ref={(child) => { this.child = child; }}/>
    )
  }
})

3) The Redux Way.

searchText is managed by the store thus the action dispatched triggers a resolver that reset the searchText value, the container updates its child and we are done, well… almost: the presentational component is a controlled component that means it manages the input text as an internal state, i think we have to find a way to make the two ‘state managers’ coexist.

I wrote this code to manage the internal state and the state coming from redux, in few words the presentational gets the initial value from redux, then updates it in the onChange event and it’s ready to receive updates from redux thanks to componentWillReceiveProps.

export default React.createClass({

  getInitialState: function () {
    return {
      searchText: this.props.searchText ==> REDUX
    }
  },

  componentWillReceiveProps: function (nextProps) {
    this.setState({
      searchText: nextProps.searchText ==> REDUX
    })
  },

  render: function () {
    return (
        <div>
          <TextField
            value={this.state.searchText}
            onChange={e => this.setState({ searchText: e.target.value })}
          />
          <RaisedButton
            onClick={this.props.startSearch.bind(null, this.state.searchText)}
          />
        </div>
    )
  }
})

4) Redux-Form To complete the picture i link the redux-form options to do that http://redux-form.com/6.5.0/docs/faq/HowToClear.md/

What do you think about those ideas? Thanks.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.