简体   繁体   English

提交后重置输入字段

[英]Reset an input field after submission

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. 我在redux-react应用程序中遇到一些处理简单情况的问题:我希望在按钮点燃异步操作后重置输入文本。

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. 假设我们有一个输入文本,您可以在其中放置文本,并通过onClick事件传递给调度操作。 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: 我已经实现了一些解决方案(我正在使用redux thunk)解决这个问题,但我不确定它们是否是解决它的黑客方法,让我告诉你:

1) Presentational component (the input field) implements a reset method that is passed as a value to the onClick method. 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>
    )
  }
})

The container dispatches the action and then calls the reset method. 容器调度操作,然后调用reset方法。

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 ) 2)使用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 容器获取对其子项的引用,并通过它调用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) The Redux Way. 3)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 ( https://facebook.github.io/react/docs/forms.html#controlled-components ) 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. searchText由商店管理,因此调度的动作触发了一个解析器,它重置了searchText值,容器更新了它的子代,我们完成了,嗯......几乎:表示组件是一个受控组件( https://facebook.github.io /react/docs/forms.html#controlled-components )这意味着它将输入文本作为内部状态进行管理,我认为我们必须找到一种方法来使两个“州经理”共存。

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 . 我编写了这段代码来管理来自redux的内部状态和状态,简言之,表示从redux获取初始值,然后在onChange事件中更新它,并且由于componentWillReceiveProps它已准备好从redux接收更新。

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/ 4)Redux-Form为了完成图片,我链接了redux-form选项来做到这一点http://redux-form.com/6.5.0/docs/faq/HowToClear.md/

What do you think about those ideas? 您如何看待这些想法? Thanks. 谢谢。

Go the Redux way, except go all the way: remove the internal state from your component completely and let Redux handle it (might as well make your component a pure-functional component too): 去Redux方式,除了一路:完全从组件中删除内部状态,让Redux处理它(也可以使你的组件成为一个纯功能组件):

Component: 零件:

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

Action creator: 行动创造者:

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

Reducer: 减速器:

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;

Hopefully that helps. 希望这会有所帮助。 Good luck! 祝好运!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM