首页 文章

将API响应数据从Redux状态传递到组件props

提问于
浏览
1

我是Redux的新手,我正在尝试调度和异步操作并返回响应数据更新的新状态 .

这是我在的地方:

App.js (容器组件)

import React, { Component } from 'react'
import { connect } from 'react-redux'

// import all actionCreators
import * as actions from '../actions/actionCreators'

// import component to pass props to
import Main from './Main'

const mapStateToProps = (state, { params, location, users }) => {
   const rootPage = params.rootPage || '';
   return {
      users,
      rootPage
   }
}

const App = connect(
   mapStateToProps,
   actions
)(Main);

export default App;

Action Creator

export const fetchRemoteData = (endpoint) => (dispatch, getState) => {
   return axios.get('https://jsonplaceholder.typicode.com/users').then(
      response =>
         dispatch({
            type: 'FETCH_REMOTE_DATA_SUCCESS',
            endpoint,
            response
         })
      )
}

Component

export default class Users extends Component {
   componentDidMount() {
      console.log('Component Mounted!')
      this.props.fetchRemoteData('users')
   }
   render() {
      const {users} = this.props
      console.log(users)
      const {rootPage} = this.props;
      return (
         <div>
            <h1>Users Page</h1>
            <p>This is the Users page and an example of how your app is working correctly</p>
            <p>rootPage: {rootPage}</p>
            {/*users.map(user =>
               <p>{user.name}</p>
            )*/}
         </div>
      )
   }
}

当我查看React Dev Tools时, users 对象不在那里,即使它在我的全局状态对象中 .

这让我觉得我可能没有正确地将它映射到我的容器组件,但我看不出这有什么问题......

Root Reducer

// import individual reducers
import users from './users'

const rootReducer = combineReducers({
   users,
   routing: routerReducer
})

export default rootReducer

是否与我的API调用是在 componentDidMount 中进行的事实有关,而我的组件在收到响应后没有注册对redux状态所做的更改?

任何帮助赞赏 .


更新:

我忘了在 mapStateToProps 函数中包含 users: state.users . 现在 users 对象在我的道具中,但它仍然不包含状态......


Main.js

import React, { Component } from 'react';
import { Link } from 'react-router'

export default class Main extends Component {
   render() {

      return (
         <div className='container'>
            <h2>Main.js (wrapped by App.js)</h2>
            <hr />
            <Link to='/'>Home</Link>
            {' | '}
            <Link to='/users'>Users</Link>
            {' | '}
            <Link to='/posts'>Posts</Link>
            <hr />

            {React.cloneElement(this.props.children, this.props)}
         </div>
      )
   }
}

注意:我正在渲染 UsersPosts 作为反应路由器 Router 组件的子项 .


新更新

好的,所以动作肯定会到达减速器,减速器肯定会更新redux商店 .

我现在拥有它,以便在调度动作后, Main 组件的道具在安装 Users 组件后根据需要更新 .

所以,我的问题几乎解决了 . 我认为现在的问题是 componentDidMount . 响应有效负载使得它成为 Main 组件道具的方式,但是当我尝试渲染响应数据时,我什么也得不到 .

Users render function:

{this.props.users ?
   this.props.users.map(user => <p>{user.name}</p>) :
   <p>No data</p>
}

所有我没有数据_2448755知道如何将 componentDidMount 中返回的数据放入我的视图中 .

我希望这更清楚 - 如果没有道歉 .

为了充分披露,这是我的 reducer

const users = (state = [], action) => {
   switch(action.type) {
      case 'FETCH_REMOTE_DATA_SUCCESS' :
         if (action.response) {
            return action.response.data
         }
      default :
         return state;
   }
   return state;
}

export default users;

1 回答

  • 2

    如果您看到正确的数据通过 mapStateToProps ,那么您应该在 Main 中看到正确的数据,这意味着将这些道具传递给 Users 也应该有效 .

    const mapStateToProps = (state, { params }) => {
      console.log(state.users) <--- make sure this is correct
    
      const rootPage = params.rootPage || '';
      return {
        users: state.users,
        rootPage
       }
    }
    

    然后在Main:

    render() {
      console.log(this.props.users) <--- make sure this is correct
    
      return (
        ...
      )
    }
    

    如果以上两个步骤记录了不正确的数据,那么就会出现一些减速器/动作(听起来不是那么好) .

    如果这些是正确的,并且您没有在Users组件中获得正确的数据,则问题在于以下行:

    {React.cloneElement(this.props.children, this.props)}
    

    我想你可能需要以不同的方式写出这一点(尽管不是100%肯定) . 我为我的孩子路线做了一个更全面的道具副本

    let children = React.Children.map(this.props.children, child => {
      return React.cloneElement(child, {
        ...child.props,
        ...this.props,
      })
    })
    

    或者,您可以 connect 您的用户组件,这可能是一个好主意,因为它's the one that'实际上使用 users

    connect(state => ({ users: state.users }))(Users)

相关问题