Node.js this.props.state的定义速度不够快?重排/反应

Node.js this.props.state的定义速度不够快?重排/反应,node.js,reactjs,redux,Node.js,Reactjs,Redux,我一直试图从状态树中筛选和访问用户。redux devtools显示了它的店面组件,但它一直说this.props.user未定义。现在我尝试console.log它,并在组件渲染几次后实现了它的定义。这很复杂,我需要一些指导 这是减速器 import { GET_USER } from '../actions/types'; import { v4 as uuidv4 } from 'uuid'; const initialState = { users: [ {

我一直试图从状态树中筛选和访问用户。redux devtools显示了它的店面组件,但它一直说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;
  }
};
店面组件

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);

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

您的解构语法有误。您试图访问属性的深度太深了一层

改变

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

编辑

我建议将GET_用户全部删除,并采取行动设置您的活动用户。这只是为了灵感,我不知道你的应用程序的使用情况。还要看一看,这将非常适合您的用例

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

首先执行一个操作,其中参数是要设置为活动的用户的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);
}

然后将MapStateTops替换为

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


现在使用activeUser.name代替user.name,您的解构语法错误。您试图访问属性的深度太深了一层

改变

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

编辑

我建议将GET_用户全部删除,并采取行动设置您的活动用户。这只是为了灵感,我不知道你的应用程序的使用情况。还要看一看,这将非常适合您的用例

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

首先执行一个操作,其中参数是要设置为活动的用户的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);
}

然后将MapStateTops替换为

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


现在不再使用user.name,而是使用activeUser.name

谢谢,我让它没有中断,但是user.name仍然没有定义。如果i console.log用户返回一个数组,但我希望它是一个对象。它将首先记录两个用户的数组,然后是console.log,只记录一个用户作为数组。我认为您混淆了两件事。为什么您希望用户是一个对象?用户:state.users.filteruser=>user.id!==action.payload过滤器函数返回数组而不是对象。reducer并不是用来作为数据选择器的,如果您想获得特定的用户,我建议您直接在组件中查找或过滤。在多次调用GET_USER之后,该状态也不会将用户作为属性,因为您只返回一个属性用户的状态。嘿,抱歉,我让它工作了,但它没有足够快地定义activeUser,它说它未定义它会使应用程序崩溃。如果控制台中的console.log activeUser返回其未定义的两次,则用户为loggedYou可以选择渲染整个组件,也可以使用{activeUser?.name&&{activeUser.name}仅渲染名称的部分。谢谢,我没有中断,但user.name仍然未定义。如果i console.log用户返回一个数组,但我希望它是一个对象。它将首先记录两个用户的数组,然后是console.log,只记录一个用户作为数组。我认为您混淆了两件事。为什么您希望用户是一个对象?用户:state.users.filteruser=>user.id!==action.payload过滤器函数返回数组而不是对象。reducer并不是用来作为数据选择器的,如果您想获得特定的用户,我建议您直接在组件中查找或过滤。在多次调用GET_USER之后,该状态也不会将用户作为属性,因为您只返回一个属性用户的状态。嘿,抱歉,我让它工作了,但它没有足够快地定义activeUser,它说它未定义它会使应用程序崩溃。如果控制台中的console.log activeUser返回其未定义的两次,则用户为loggedYou可以选择性地呈现整个组件,也可以使用{activeUser?.name&&{activeUser.name}仅呈现名称的部分