簡體   English   中英

如何將重做redux的動作創建者變成Promise?

[英]How to turn redux-thunk action creator into Promise?

我有以下異步動作創建者(使用redux-thunk):

export const nextPupil = () => {
    return (dispatch, getState) => {
    const {activeSentence, sentencesList} = getState();
    //... some more code
    const nextActive = pupilList[nextIndex];

    dispatch({ type: "UPDATE_ACTIVE", payload: nextActive });
  }
};

但是,我需要執行此操作以返回承諾,因為我需要在我的一個組件中等待其完成,然后再執行其他操作(請參閱此問題以獲取有關我的問題的更詳細說明)

我該如何將這個動作變成一個承諾並仍然使用redux-thunk? 非常感謝。

編輯:

我知道我正在嘗試將輸入字段的狀態保存在本地組件中,而不是保存在Redux中。 這是因為如果我將輸入字段的值直接綁定到redux存儲,它將不再可編輯。 但是,我希望用戶能夠編輯輸入字段,然后在提交時將編輯后的值保存在我的redux存儲中。 如果我直接綁定東西,則用戶將無法更改值/進行編輯。

我認為您誤解了通過redux的數據流。 我假設當您要將操作轉變為一個承諾時,您希望該承諾在更新redux狀態時得到解決-另一個問題似乎就是這種情況。 通常,這不是設計redux的方式。

當您分派動作時,商店將被更新,然后來自商店的組件中的道具將被更新。 您需要做的就是在組件中使用這些道具,並且只要道具更新,組件也將使用。

在最初的問題中,您的代碼是:

onSubmit(e) {
  e.preventDefault();
  this.props.nextSentence(); //this is async

  this.setState({ //this is not yet updating with the right values then
      inputField: this.props.activePupil.name
  });
}

您遇到的問題是, activePupil是您的redux存儲的一部分,但是您也試圖將其存儲在組件的狀態內。 這是一個壞主意,因為您再也無法為自己的狀態提供單一的真理來源。

更好的方法是在需要的地方使用this.props.activePupil ,例如

 render() {
     return (
        <span>{this.props.activePupil.name}</span>
     );
 }

現在,當您分派操作時,存儲一經更新,組件也會隨之更新。 如果需要,則可以在商店中添加loading屬性,以便可以向用戶指示正在發生的事情,並在執行任何異步工作之前從thunk中分派此事件,然后在分派UPDATE_ACTIVE時恢復loading

export const nextPupil = () => {
    return (dispatch, getState) => {
      dispatch({ type: "PUPIL_UPDATING });
      const {activeSentence, sentencesList} = getState();
      //... some more code
      const nextActive = pupilList[nextIndex];

      dispatch({ type: "UPDATE_ACTIVE", payload: nextActive });
  }
};

編輯1

我們花了點時間考慮下面的解決問題的正確方法,但是我認為我已經確定了一種合理的方法來實現它,同時又保持了數據完整性。 它確實涉及將表單輸入保存在您的商店中,並不是每個人都喜歡它,但對我來說不是問題。

無論如何...我們需要另一個reducer來處理用戶輸入-這將非常簡單並響應兩個動作-您已經擁有的“ UPDATE_ACTIVE”動作和“ NAME_UPDATED”動作:

const updatedName = (state = '', action) => {
  switch (action.type) {
    case 'UPDATE_ACTIVE':
        return action.payload.name;
    case: 'NAME_UPDATED':
        return action.payload.updatedName;
    default:
        return state;
  }
};

然后,我們將需要一個簡單的動作創建者:

const inputChanged = updatedName => ({
     type: 'NAME_UPDATED',
     payload: { updatedName }
});

現在,在我們的組件中,我們將使用新創建的狀態和動作創建者來管理我們的輸入(只需照常connect它們)-這里缺少很多代碼,但應該足夠理解。

class Whatever extends React.Component {
    constructor() {
        super();
        this.handleChange= this.handleChange.bind(this);
    }

    handleChange(event) {
        this.props.inputChanged(event.target.value);
    }

    render() {
        return (
            <input type="text" value={this.props.updatedName} onChange={this.handleChange} />
        );
    }
}

我希望這是有道理的!

編輯2:

如果您想將輸入存儲在組件狀態上而不是在redux存儲中,那么我認為這種方法應該可行。 它使用componentWillReceiveProps生命周期掛鈎 -設置組件狀態,即activePupil更改時的輸入值。 每次道具更新時都會調用此方法,但是在道具沒有任何更改時也可能會調用它,因此我們需要一些邏輯來決定是否更新updatedPupilName道具。 為此,我們將當前的props.activePupil.namenextProps.activePupil.name進行比較,並且僅在狀態不同時才更新狀態。 如果您的學生具有ID類型屬性,則可能更適合進行比較。

class Whatever extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            updatedPupilName: props.activePupil.name
        };
        this.handleChange= this.handleChange.bind(this);
    }

    componentWillReceiveProps(nextProps) {
        if (nextProps.activePupil.name !== this.props.activePupil.name) {
            this.setState({
                updatedPupilName: nextProps.activePupil.name
            });
        }
    }

    handleChange(event) {
        this.setState({
            updatedPupilName: event.target.value
        });
    }

    render() {
        return (
            <input type="text" value={this.state.updatedPupilName} onChange={this.handleChange} />
        );
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM