提交后重置输入字段

时间:2017-03-03 08:12:44

标签: javascript forms reactjs redux redux-form

我在redux-react应用程序中遇到一些处理简单案例的问题:我想在按钮点燃异步操作后重置输入文本。

假设我们有一个输入文本,您可以在其中放置文本,并通过onClick事件传递给调度操作。 此操作与服务器联系,在服务器响应后,我想重置输入字段。

我已经实现了一些解决方案(我正在使用redux thunk)解决这个问题,但我不确定它们是否是解决问题的方法,让我告诉你:

1)演示组件(输入字段)实现一个重置方法,该方法作为值传递给onClick方法。

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>
    )
  }
})

容器调度操作,然后调用reset方法。

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

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

容器获取对其子项的引用并通过它调用reset

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)Redux Way。

searchText由商店管理,因此调度的动作触发了一个解析器,重置了searchText值,容器更新了它的子,我们完成了,好吧......差不多: 表示组件是一个受控组件(https://facebook.github.io/react/docs/forms.html#controlled-components),这意味着它将输入文本作为内部状态进行管理,我认为我们必须找到一种方法使两个“州经理”共存。

我编写了这段代码来管理来自redux的内部状态和状态,简言之,表示从redux获取初始值,然后在onChange事件中更新它,并且它已准备好从redux接收更新,这要归功于 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 为了完成图片,我链接了redux-form选项来做到这一点 http://redux-form.com/6.5.0/docs/faq/HowToClear.md/

您如何看待这些想法? 感谢。

1 个答案:

答案 0 :(得分:1)

使用Redux方式,除了一路:完全从组件中删除内部状态,让Redux处理它(也可以使组件成为纯功能组件):

组件:

import { connect } from 'redux';
import { actions } from 'actionCreators';

const ControlledInputComponent = (props) => {
  return (
    <div>
      <TextField
        value={this.props.searchText}
        onChange={e => this.props.setSearchText(e.target.value)}
      />
      <RaisedButton
        onClick={this.props.startSearch}
      />
    </div>
  );
};

const mapStateToProps = (state) => {
  return { searchText: state.searchText  };
};

const mapDispatchToProps = (dispatch) => {
  return {
    setSearchText: (txt) => { dispatch(actions.setSearchText(txt)); },
    startSearch: () => { dispatch(actions.search()); }
  };
};

export default connect(mapStateToProps, mapDispatchToProps)(ControlledInputComponent);  

行动创作者:

export const actions = {
  setSearchText: (txt) => ({ type: 'setText', data: txt }),

  //here's where the thunk comes in
  //make sure you have redux-thunk and add it as a middleware when setting up the store, etc.

  search: () => {
    return (dispatch) => {
      //use fetch or whatever to run your search (this is a simplified example)
      fetch(/* your url here */).then(() => {
        //presumably a success condition

        //handle the search results appropriately...

        //dispatch again to reset the search text
        dispatch(actions.setSearchText(null);
      });
    };
  }
};

减速机:

const reducer = (state = { searchText: null }, action) => {
  if (!action || !action.type) return state;
  switch (action.type) {

    //you should really define 'setText' as a constant somewhere
    //so you can import it and not have to worry about typos later
    case 'setText':
      return Object.assign({}, state, { searchText: action.data });

    default:
      return state;
  }
};

export default reducer;

希望这会有所帮助。祝你好运!