繁体   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