如何在等待 redux 解决时禁用按钮?

Posted

技术标签:

【中文标题】如何在等待 redux 解决时禁用按钮?【英文标题】:How to disable a button while waiting for redux to resolve? 【发布时间】:2016-02-24 12:17:23 【问题描述】:

在以下示例中,如何在地理定位请求期间禁用该按钮?在初始化时未设置 this.props.inProgress ,我想在请求 getCurrentPosition 时禁用按钮并在 RECEIVE_LOCATION 解决时启用。什么是正确的做法?我是否要使用状态并将道具复制到 GeoButton?

export function getGeolocation() 
  return dispatch => 
    if (navigator.geolocation) 
      navigator.geolocation.getCurrentPosition(function(position) 
        dispatch(
          type: 'RECEIVE_LOCATION',
          coords: 
            latitude: position.coords.latitude,
            longitude: position.coords.longitude,
            inProgress: false,
          ,
        );
      );
    
  

export function geolocation(state=, action) 
  switch (action.type) 
    case 'RECEIVE_LOCATION':
      var newState = action.coords;

      return newState;
    default:
      return state;
  



class GeoButton extends React.Component 
  constructor(props) 
    super(props);
  

  findLocation(e) 
    e.preventDefault();
    this.props.dispatch(getGeolocation());
  
  render() 
    console.log(this.props); // on init geolocation object is empty
    var self = this;
    return (
      <div>
        <button type="button" onClick=this.findLocation disabled=self.props.geolocation.inProgress>Get location</button>
      </div>
    )
  


export default connect(state => (
  geolocation: state.geolocation
))(GeoButton); // just gives it dispatch()

【问题讨论】:

你不能使用 inProgress 标志吗?像 disabled="inProgress" 在构造函数中设置与预期数据相对应的状态对象并在解决时用该数据替换该状态不是更好吗?我不确定在这种情况下哪种方法是正确的,当前的解决方案不起作用。 【参考方案1】:

在 redux 中做 async 的时候,经常需要调用 dispatch 两次。一同步一异步。

您的操作应如下所示:

export function getGeolocation() 
  return dispatch => 
    dispatch( type: 'FETCHING_LOCATION' );
    if (navigator.geolocation) 
      navigator.geolocation.getCurrentPosition((position) => 
        dispatch(
          type: 'RECEIVE_LOCATION',
          coords: 
            latitude: position.coords.latitude,
            longitude: position.coords.longitude
          
        );
      );
    
  ;

你的减速器应该是这样的。我调整了 state 对象的结构,将应用数据与 ui 数据分开。

export function geolocation(state = , action) 
  switch (action.type) 
    case 'RECEIVE_LOCATION':
      return 
        coords: action.coords,
        inProgress: false
      ;
    case 'FETCHING_LOCATION':
      return 
        coords: null,
        inProgress: true
      ;
  
  return state;

无需在动作创建器中设置 inProgress 标志。 reducer 可以从 action 类型中派生出来。

【讨论】:

以上是关于如何在等待 redux 解决时禁用按钮?的主要内容,如果未能解决你的问题,请参考以下文章

Redux - 如何调用一个动作并等待它解决

如何在 React/Redux 中本地管理组件的状态

在redux中按下重置按钮时如何初始化所有状态

如何键入 Redux thunk 动作创建者以返回承诺

在使用 redux-observables 开始另一个史诗之前,如何等待不同的史诗完成并更新商店?

如何避免或禁用 Redux 表单文本输入中的自动完成功能?