массив теряется при рендеринге - PullRequest
0 голосов
/ 21 октября 2018

У меня есть файл MYProfile.js, который работает нормально.Я удалил раздел импорта и стилей.

class MyProfile extends Component {
  constructor({match}) {
    console.log("constructor");
    super()
    this.state = {
      user: '',
      redirectToSignin: false
    };
    this.match = match;
  }

  init = (userId) => {
    console.log("init");
    const jwt = auth.isAuthenticated();
    read({
      userId: userId
    }, {t: jwt.token}).then((data) => {
      if (data.error) {
        this.setState({redirectToSignin: true})
      } else {
        console.log(data);
        this.setState({user: data});
        console.log(this.state.user.roles);
      }
    })
  }

  componentWillReceiveProps = (props) => {
    console.log("componentWillReceiveProps");
    this.init(props.match.params.userId)
  }

  componentDidMount = () => {
    console.log("componentDidMount");
    this.init(this.match.params.userId)
  }

  render() {
    console.log("render");
    const {classes} = this.props;
    const redirectToSignin = this.state.redirectToSignin;
    if (redirectToSignin) { return <Redirect to='/signin'/> }
    return (
      <Paper className={classes.root} elevation={4}>
        <Typography type="title" className={classes.title}>
          Profile
        </Typography>
        <List dense>
          <ListItem>
            <ListItemAvatar>
              <Avatar>
                <Person/>
              </Avatar>
            </ListItemAvatar>
            <ListItemText primary={this.state.user.name} secondary={this.state.user.email} /> 
          </ListItem>
          <Divider/>
          <ListItem>
            <Typography>Your Profile ID: {this.state.user._id}</Typography>
          </ListItem>
          <ListItem>
            <Typography>You are assigned the following Roles: </Typography>
          </ListItem>
          <Divider/>
          <ListItem>
            <ListItemText primary={"Joined: " + (
              new Date(this.state.user.created)).toDateString()}/>
          </ListItem>
        </List>
      </Paper>
    )
  }
}

MyProfile.propTypes = {
  classes: PropTypes.object.isRequired
}

export default withStyles(styles)(MyProfile)

На консоли я получаю следующий вывод

MyProfile.js?dec7:33 constructor
MyProfile.js?dec7:69 render
MyProfile.js?dec7:64 componentDidMount
MyProfile.js?dec7:43 init
MyProfile.js?dec7:51 {status: "New", roles: Array(3), created: "2018-09-20T16:14:58.110Z", _id: "5ba3c7829708249ed4c3ce5b", name: "avinash", …}
MyProfile.js?dec7:69 render
MyProfile.js?dec7:53 (3) [{…}, {…}, {…}]

Роли показывают мне:

  (3) [{…}, {…}, {…}]
  0: {Module: "Core", Role: "Owner"}
  1: {Module: "Core", Role: "Administrator"}
  2: {Module: "Core", Role: "Regular User"}
  length: 3
  __proto__: Array(0)

Теперь япланируйте рендеринг ролей, чтобы пользователь мог видеть, какие роли ему назначены.Итак, я добавляю этот блок кода в раздел рендеринга непосредственно перед последним

  <ListItem>
    <Typography>You are assigned the following Roles: </Typography>
  </ListItem>
  {
    this.state.user.roles.map((item, i)=>{
      console.log(item);
      <ListItem key={i}>{item.Module}-{item.Role}</ListItem>
    })
  }
  <Divider/>

и получаю эту ошибку:

MyProfile.js?dec7:33 constructor
MyProfile.js?dec7:69 render
MyProfile.js?dec7:33 constructor
MyProfile.js?dec7:69 render
Uncaught TypeError: Cannot read property 'map' of undefined
    at ProxyComponent.render (MyProfile.js?dec7:95)
    at ProxyComponent.hotComponentRender (react-hot-loader.development.js?c2cb:578)
    at ProxyComponent.proxiedRender (react-hot-loader.development.js?c2cb:586)
    at finishClassComponent (react-dom.development.js?61bb:8389)
    at updateClassComponent (react-dom.development.js?61bb:8357)
    at beginWork (react-dom.development.js?61bb:8982)
    at performUnitOfWork (react-dom.development.js?61bb:11814)
    at workLoop (react-dom.development.js?61bb:11843)
    at renderRoot (react-dom.development.js?61bb:11874)
    at performWorkOnRoot (react-dom.development.js?61bb:12449)

Я пытался найти тип переменнойиспользуя typeof (this.state.user.roles), он говорит - Object.Погуглил и обнаружил, что это уместно.Я попытался привести его к массиву, чтобы я мог использовать карту, но не получилось.Я уверен, что переменная состояния role - это Array, но она становится неопределенной, как только она входит в render-return ().

Я что-то упустил?Пожалуйста, помогите ... уже провел все выходные на этом.: (

Большое спасибо за помощь в ожидании.

1 Ответ

0 голосов
/ 21 октября 2018

Сначала, когда ваш компонент монтируется, this.state.user - это строка, а не объект, поэтому внутри нет ролей.

Роли изначально не определены, поэтому для этой неопределенной переменной нет карты, и, конечно, итерации вообще не происходит ...

Поэтому вы должны определить ее как пустой массив, чтобы предотвратитьошибка.

constructor({match}) {
    console.log("constructor");
    super()
    this.state = {
      user: {roles:[]},
      redirectToSignin: false
    };
    this.match = match;
  }

Дополнительно / альтернативно, вы можете убедиться, что роли не определены до итерации.

{
    this.state.user.roles && this.state.user.roles.map((item, i)=>{
      console.log(item);
      <ListItem key={i}>{item.Module}-{item.Role}</ListItem>
    })
  }
...