首页 > 解决方案 > Redux 操作未从 api (json) 获取数据

问题描述

在我的项目中使用 React+Redux+Django Rest Framework,我被卡住了。我正在尝试通过内部带有 axios 请求的 redux 操作从 api (drf json) 获取数据。我有一个广告列表和广告。

对于第一次渲染,它会给我数据响应,但是当我返回并从广告列表中选择另一个广告时,它不会渲染(没有 selectedAdvert [空数组] 操作不起作用)。它仅在重新加载页面后呈现选定的广告。你能帮我让它正常工作吗?这是我的代码...

动作/index.js

export function getAdvert() {
  return function(dispatch) {
    axios.get('/api/adverts/')
        .then(response => dispatch({
                type: GET_ADVERTS,
                payload: response.data
            })
        );
  }

export function getSelectedAdvert(id) {
   return function(dispatch) {
    axios.get(`/api/adverts/${id}/`)
        .then(response => dispatch({
            type: GET_SELECTED_ADVERT,
            payload: response.data
        }));
   }
}

export function clearSelectedAdvert() {
  return {
    type: CLEAR_SELECTED_ADVERT,
    payload: []
  }

advert_reducer.js

import {
  GET_SELECTED_ADVERT,
  CLEAR_SELECTED_ADVERT,
  GET_ADVERTS
} from '../actions/types';

export default function(state = {}, action) {
  switch(action.type) {
    case GET_ADVERTS:
        return {
            ...state, advert: action.payload
        };
    case GET_SELECTED_ADVERT:
        return {
            ...state, selectedAdvert: action.payload
        };
    case CLEAR_SELECTED_ADVERT:
        return {
            ...state, selectedAdvert: action.payload
        };
    default:
        return state;
   }
}

广告.js

import { getSelectedAdvert, clearSelectedAdvert } from '../actions';
import { bindActionCreators } from 'redux';
import { withRouter } from 'react-router-dom';

class Advert extends React.Component {
constructor(props) {
  super(props);
}

componentDidMount() {
    this.props.getSelectedAdvert(this.props.match.params.id);
}

componentWillUnmount() {
    this.props.clearSelectedAdvert();
}

renderAdvert = ({selectedAdvert}) => {
    console.log(selectedAdvert);
      if(selectedAdvert) {
            return (
                <div className="advert mi-5" key={selectedAdvert.id}>
                    <div className="advert__main">
                        <div className="advert__photo">
                            <div className="lightbox__image">
                                <img width="100%" src={selectedAdvert.images[0]}/>
                            </div>
                        </div>

                        <div className="advert__order">
                            <h4>{selectedAdvert.title}</h4>
                            <hr/>
                            <div>
                                <p>{selectedAdvert.price}</p>
                            </div>
                            <button>
                                Order
                            </button>
                        </div>
                    </div>
                </div>
            )
    }
};

render() {
    return (
        <div className="container">
            <div className="row">
                {this.renderAdvert(this.props.advert)}
            </div>
        </div>
    );
  }
}

function mapStateToProps(state) {
   return {
      advert: state.advert
   }
}

function mapDispatchToProps(dispatch) {
   return bindActionCreators({getSelectedAdvert, clearSelectedAdvert}, 
   dispatch);
}

export default connect(mapStateToProps, mapDispatchToProps)(withRouter(Advert));

产品js

import React from 'react';
import { connect } from 'react-redux';
import { withRouter } from 'react-router-dom';
import { bindActionCreators } from 'redux';
import { getAdvert, clearSelectedAdvert } from "../actions/index";
import Card from "../components/app/Card";

class Products extends React.Component {
  componentDidMount() {
      this.props.getAdvert();
  }

renderProducts = ({advert}) => {
    if(advert) {
        return advert.map(product => {
            return (
                <Card key={product.id} advertItem={product}/>
            )
        })
    }
};

 render() {
    return (
         <div className="product__card-box">
             {this.renderProducts(this.props.advert)}
         </div>
 )}

function mapStateToProps(state) {
console.log(state);
   return {
      advert: state.advert
   }
}

function mapDispatchToProps(dispatch) {
   return bindActionCreators({ getAdvert, clearSelectedAdvert }, dispatch)
}


export default connect(mapStateToProps, mapDispatchToProps)(withRouter(Products));

Card.js

const Card = ({advertItem}) => {
return (
    <div key={advertItem.id}>
        <div>
            <img src={advertItem.images[0]} alt={advertItem.title}/>
            <div>{advertItem.price}</div>
        </div>

        <div>
            <div>{advertItem.title}</div>
            <div>
                <Link className="btn order__btn" to={`/advert/${advertItem.id}/`}>More</Link>
            </div>
        </div>
    </div>
  )
};

export default Card;

标签: reactjsapireduxdjango-rest-framework

解决方案


推荐阅读