this.props.state定义得不够快?还原/反应

发布时间:2020-07-07 15:41

我一直试图从状态树中筛选和访问用户。 redux devtools显示它在StoreFront组件中,但一直说this.props.user是未定义的。现在我尝试用console.log记录它,并在组件渲染几次后实现它的定义。它只是很复杂,我需要一些指导。

减速机

import { GET_USER } from '../actions/types';
import { v4 as uuidv4 } from 'uuid';


const initialState = {
  users: [
    {
      id: 2,
      name: 'joe',
      email: 'joeiscool@gmail.com',
      password :'joe6969'
    },
    {
      id: uuidv4(),
      name: 'sally',
      email: 'joeishunky@gmail.com',
      password :'bigbooty45678'
    }
  ]
}


export default function(state = initialState, action){
  switch(action.type){
    case GET_USER:
     return {
       user: state.users.filter(user => user.id !== action.payload)
     }
     default:
       return state;
  }
};

StoreFront组件

import React, { Component } from 'react';
import { Card, Button, Container, Row } from 'react-bootstrap'
import { connect } from 'react-redux';
import { getProducts } from '../actions/productActions';
import { getUser } from '../actions/userActions';
import PropTypes from 'prop-types';

class Storefront extends Component {
 componentDidMount() {
   this.props.getProducts();
   this.props.getUser(2);

 }

  render(){
    const { products } = this.props.product;
    const { user } = this.props.user;
    return(
      <div style={productDisplayStyle}>
          <Container style={{justifyContent: 'center'}}>
           <Row style={{justifyContent: 'space-around'}}>
            {products.map(({ id, info, price, img}) => (
              <Card style={{ width: '18rem', border: 'none',padding:'5px'  }} key={id}>
                 <Card.Img variant="top" src={img} className='productImg'/>
                 <Card.Body>
                   <Card.Title>{user.name}</Card.Title>
                   <Card.Text>
                     {info}
                   </Card.Text>
                   <Card.Text style={{fontSize: '30px'}}>{price}</Card.Text>
                   <Button variant='info'>Add To Cart!</Button>
                 </Card.Body>
             </Card>
            ))}

          </Row>
        </Container>
    </div>
    )
  }
}

const productDisplayStyle =
  {
    width: '90%',
    backgroundColor: '#fff',
    margin:'auto',
    padding: '5px'
  }

Storefront.propTypes = {
  getProducts: PropTypes.func.isRequired,
  product: PropTypes.object.isRequired,
  getUser: PropTypes.func.isRequired,
  user: PropTypes.object.isRequired
}

const mapStateToProps = (state) => ({
  product: state.product,
  user: state.user
})

export default connect(mapStateToProps, { getProducts, getUser })(Storefront);

如果您需要其他任何信息,请告诉我。我真的很需要帮助

回答1

您使用错误的解构语法。您试图将属性访问的层次太深。

更改

const { products } = this.props.product;
const { user } = this.props.user;

const {products, user} = this.props

编辑

我建议一起摆脱GET_USER,并采取措施来设置“活动用户”。这只是出于启发,我不知道您的应用程序的用例。还请看一下reselect,这完全适合您的用例。

我将提供一个可行的示例,根据您的需要进行编辑...

首先执行一个操作,其中参数是要设置为活动用户的ID。称为setActiveUserById

然后将此代码添加到减速器中。注意,我使用了find而不是filter。 find()方法返回所提供数组中满足所提供测试功能的第一个元素

export default function(state = initialState, action){
  switch(action.type){
    case SET_ACTIVE_USER_BY_ID:
    return {
      ...state,
      activeUser: state.users.find(user => user.id === action.activeUserId)
    }
    default:
      return state;
  }
};

在您的组件中设置活动用户

替换

componentDidMount() {
  this.props.getProducts();
  this.props.getUser(2);
}

使用

componentDidMount() {
  this.props.getProducts();
  this.props.setActiveUserById(2);
}

然后将mapStateToProps替换为此

const mapStateToProps = (state) => ({
  product: state.product,
  activeUser: state.activeUser
})

const {products, activeUser} = this.props

现在,不要使用user.name,而要使用activeUser.name