首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么我的动作创建器在使用thunk时被调用的顺序是错误的?

为什么我的动作创建器在使用thunk时被调用的顺序是错误的?
EN

Stack Overflow用户
提问于 2020-12-06 11:33:13
回答 1查看 28关注 0票数 0

我正在尝试redux-thunk和动作创建器,并注意到一些我不理解的奇怪行为。当我调用动作创建器函数时,它们没有按照我想要的顺序被调用。这是我的App.js组件

代码语言:javascript
复制
class App extends Component {

  handleSave = () => {
    this.props.postData({
      name:this.props.activity,
      type_name: this.props.type
    })
    this.props.fetchList()
    this.props.fetchData()
  }

  handleClick = () => {
    this.props.fetchData()
  }

  componentDidMount() {
    this.props.fetchData()
    this.props.fetchList()
  }

  render() {
    return (
      <div className="App">
        <Router>
          <Nav />
          <Route exact path='/' render={props => <Home {...props} clickProp={this.handleClick} saveProp={this.handleSave}/>} />
          <Route exact path='/activities' render={props => <ListContainer {...props} numItems={this.props.list.length} listProp={this.props.list}/>} />
        </Router>
      </div>
    );
  }
}

const mapStateToProps = state => {
  return {
    activity: state.activity,
    type: state.type,
    list: state.list
  }
}

const actions = {fetchData, fetchList, postData}
export default connect(mapStateToProps, actions)(App);

当我单击Home子组件中的一个按钮时,将调用handleSave函数,该函数将把一个项目发布到我的列表中,然后获取更新后的列表,以便它可以显示在我的列表中。当我这样做时,this.props.fetchList()首先被调用,即使它是第二个被调用的函数。我在我的reducer中放置了一个console.log(动作),这是打印出来的。

代码语言:javascript
复制
{type: "FETCH_LIST", payload: Array(86)}
{type: "POST_DATA", payload: {…}}
{type: "FETCH_DATA", payload: {…}}

让FETCH_LIST在POST_DATA之后发生的唯一方法是再次调用fetch_data(),如下所示

代码语言:javascript
复制
  handleSave = () => {
    // something weird going on here
    this.props.fetchList()
    this.props.postData({
      name:this.props.activity,
      type_name: this.props.type
    })
    this.props.fetchList()
    this.props.fetchData()
  }

如果可能的话,我真的希望能够让我的代码工作,而不必调用相同的函数两次。最后,这是我的动作创建者的样子。

代码语言:javascript
复制
export default function fetchData() {
  return (dispatch) => {
    const url = 'http://www.boredapi.com/api/activity/'
    fetch(url)
      .then(res => res.json())
      .then(activity => { dispatch({type: "FETCH_DATA", payload: activity})})
  }
}

export default function fetchList() {
  return (dispatch) => {
    const url = 'http://localhost:3001/activities'
    fetch(url)
      .then(res => res.json())
      .then(list => { dispatch({type: "FETCH_LIST", payload: list})})
  }
}

export default function postData(activity) {
  return (dispatch) => {
    const url = 'http://localhost:3001/activities'
    const config = {
      method: 'POST',
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({activity})
    }

    fetch(url, config)
      .then(r => r.json())
      .then(activity => {dispatch({type: "POST_DATA", payload: activity})})
  }
}

我唯一的猜测是,这种情况之所以发生,是因为这些操作是异步的。因此,我还尝试更改这些函数的调用顺序,无论发生什么,FETCH_LIST总是在POST_DATA之前发生。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-12-06 13:18:04

您可以将这些操作创建器转换为async版本,然后可以等待它们,以便它们按顺序执行。

https://medium.com/@gaurav5430/async-await-with-redux-thunk-fff59d7be093

例如在你的fetchData

代码语言:javascript
复制
function fetchData() {
  return async (dispatch) => {
    const url = 'http://www.boredapi.com/api/activity/'

    try{
      const res = await fetch(url)
      const activity = await res.json();
      dispatch({type: "FETCH_DATA", payload: activity})
    }
    catch (error) {
      console.log(error);
    }
}

一旦它们是async,你就可以在你的handleSave中等待它们(一旦你将它转换成async),这将确保它们被按顺序调用。

代码语言:javascript
复制
handleSave = async () => {
    await this.props.postData({
      name:this.props.activity,
      type_name: this.props.type
    })
    await this.props.fetchList()
    await this.props.fetchData()
  }
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65164412

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档