6

次の例では、位置情報のリクエスト中にボタンを無効にするにはどうすればよいですか? this.props.inProgress が init に設定されていないため、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()
4

1 に答える 1

9

redux で async を実行する場合、多くの場合、dispatch を 2 回呼び出す必要があります。1 つは同期、もう 1 つは非同期です。

アクションは次のようになります。

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

レデューサーは次のようになります。状態オブジェクトの構造を微調整して、アプリ データを 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 フラグを設定する必要はありません。レデューサーは、アクション タイプからそれを派生させることができます。

于 2015-11-22T11:26:52.070 に答える