Массив теряется при рендеринге

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

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

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

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

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

  render() {
    console.info("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.info(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. Погуглил и нашел, что это подходит. Я попытался преобразовать его в массив, чтобы использовать карту, но не смог. Я уверен, что переменная состояния ролей - это массив, но она становится неопределенной, как только входит в render-return ().

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

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

мой ответ решил вашу проблему?

aquiseb 22.10.2018 15:13
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
0
1
23
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

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

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

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

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

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

Большое спасибо ... все эти уловки основаны на опыте :) Отличная работа. Большое спасибо.

Avinash 22.10.2018 15:57

Другие вопросы по теме