我有以下异步动作创建者(使用 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 的设计方式。
当你 dispatch 一个 action 时,store 会更新,然后你的组件中来自 store 的 props 会更新。您需要做的就是在您的组件中使用这些 props,并且每当 props 更新时,您的组件也会更新。
在您最初的问题中,您的代码是:
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>
);
}
现在,当您调度操作时,一旦 store 更新,您的组件也将更新。如果您需要,那么您可以loading
向您的商店添加一个属性,以便您可以向用户指示正在发生的事情,并在执行任何异步工作之前从您的 thunk 中分派它,然后loading
在UPDATE_ACTIVE
分派时恢复。
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 });
}
};
下面对解决您的问题的正确方法进行了一些思考,但我认为我已经确定了一种合理的方法来实现它,同时保持数据完整性。它确实涉及在您的商店中保留表单输入,这不是每个人都喜欢的,但对我来说不是问题。
无论如何......我们需要另一个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} />
);
}
}
我希望这是有道理的!
如果您想将输入存储在组件状态而不是 redux 存储中,那么我认为这种方法应该可行。它使用componentWillReceiveProps 生命周期钩子- 设置组件状态,即activePupil
prop 更改时的输入值。每次 props 更新时都会调用它,但也可能在没有任何 props 更改时调用,因此我们需要一些逻辑来决定是否更新updatedPupilName
prop。为了实现这一点,我们将当前的状态与状态进行比较props.activePupil.name
,nextProps.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} />
);
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句