Я получаю сообщение «this.props.comments.map is not a function» или другие ошибки, если нажимаю на фотографию после удаления другой фотографии в моем приложении MERN. - PullRequest
0 голосов
/ 10 июля 2020

Когда я удаляю фотографию из своего приложения, я не могу щелкнуть ни одну из других, не обновляя страницу. Приложение представляет собой веб-сайт, написанный на стеке MERN с помощью Redux. Это простой поток фотографий, который вы можете щелкнуть и просмотреть фотографию на отдельной странице с комментариями.

Проблема в том, что после удаления фотографии из потока я не могу щелкнуть другие фотографии, не получив ' Невозможно прочитать свойство неопределенной ошибки. Если я обновлю sh страницу, я снова смогу щелкнуть любую фотографию. Вы можете посетить сайт здесь , загрузить фотографию, удалить фотографию, затем щелкнуть другую фотографию, чтобы увидеть пустой экран и ошибку в консоли.

Когда я запускаю приложение локально Я получаю немного другие ошибки, но проблема в пустых массивах. Иногда в сообщении об ошибке говорится: «this.props.comments.map не является функцией», а иногда - «TypeError: невозможно прочитать свойство« filename »со значением null», поэтому по какой-то причине DOM считает (?), Что фотографии и комментарии пусты. массивы? Я надеюсь, что смогу предоставить достаточно информации между компонентами React, действиями Redux и редукторами и сервером NodeJS.

enter image description here

Since the error is showing the comment 'action' I will start by displaying that function.

export const individualComments = filename => (dispatch) => {
  axios
    .get(`/api/comments/comments/${filename}`)
    .then(res =>
      dispatch({
        type: INDIV_COMMENTS,
        payload: res.data
      })
    )
  .catch(err =>
    dispatch(returnErrors(err.response.data, err.response.status))
  );
}

We are still in Redux with this next block of code. Here is the reducer for this action. The case INDIV_COMMENTS

export default (state = defaultState, action) => {
  switch (action.type) {

    case INDIV_COMMENTS:
      return {
        ...state,
        comments: action.payload
      }

      default:
      return state;    
  }
}  

Next we will move out of Redux, out of the client.
Here is that route the action calls from the server side in /api.

router.get('/comments/:filename', (req, res) => {
  Comment.find({page: req.params.filename
    }, (err, files) => {
      // Check if files
      if (!files || files.length === 0) {
        return res.json(files);
      } else if (files) {
        return res.json(files);
      }  else {
        return res.json(err);
      }
    }
  );
});  

Here is a part of the React component in one of the errors.

class Post extends React.Component {
  constructor(props) {
    super(props)
    this.submitFormHandler = this.submitFormHandler.bind(this)

  }
  componentDidMount() {
    this.props.singleView(this.props.match.params.filename);
    this.props.individualComments(this.props.match.params.filename);
    window.scrollTo(0, 0);
  }

  submitFormHandler = (e) => {
    e.preventDefault();
    const ncomment = (this.refs.aComment.value)
    const page = this.props.match.params.filename
    this.props.commentUploader(ncomment, page)
    this.refs.aComment.value = '';
  }

  render() {
    if(!this.props.comments && !this.props.photos ) {
      return (
     Загрузка ... )} else {return (

... Пропуск кода React здесь для краткости

            <h4 className="another-comment">Comments</h4>
            {this.props.comments.map(post => (
            <div className="post-card" key={post._id}>
                <div className="card-content">
                    <span className="card-title  red-text">Date:{post.date}</span>
                  <p className="comment-text-in">Comment: {post.content}</p>
                </div>
              </div>))}  

... Пропуск еще кода React здесь для краткости

const mapStateToProps = (state) => {
  return {
    array: state.photos.array,
    comments: state.comments.comments
  }
}

export default connect(mapStateToProps,
  { allPhotos, singleView, commentUploader,
    individualComments })(Post); 

Спасибо за ваше Помощь. Надеюсь, я предоставил достаточно информации.

Ответы [ 2 ]

0 голосов
/ 10 июля 2020

Я решил это, посмотрев на состояние с помощью расширения браузера Redux Devtools. Проблема заключалась в имени файла, связанном с комментариями после удаления комментариев к файлу. Я установил действие comments: action.payload, хотя должно было быть comments: null. Действие комментария запрашивало у БД комментарии к удаленной фотографии. Это происходило только за кулисами, потому что имя файла в браузере запрашивало правильную (нажатую) фотографию.

  export default (state = defaultState, action) => {
    switch (action.type) {

      case INDIV_COMMENTS:
        return {
          ...state,
          comments: action.payload
        }
        default:
        return state;    
    }
  }    

Изменено на

  export default (state = defaultState, action) => {
    switch (action.type) {

      case INDIV_COMMENTS:
        return {
          ...state,
          comments: null
        }

        default:
        return state;    
    }
  }  
0 голосов
/ 10 июля 2020

Несколько вещей:

  1. Каждый раз, когда вы видите «Невозможно прочитать свойство неопределенного» или «Невозможно прочитать свойство нулевого значения», вы должны определить, почему объект, на который вы смотрите, неожиданно оказался неопределенным / ноль. Например, в случае Cannot read property 'filename' of null' вы должны просмотреть все строки, которые обращаются к свойству filename, и определить, почему объект, к которому вы обращаетесь, имеет значение null. В этом случае вопрос заключается в том, что может привести к тому, что this.props.match.params будет нулевым.
  2. Каждый раз, когда вы видите this.props.comments.map, вы знаете, что comments не является массивом (пустым или нет). Может быть, это объект или строка, но, вероятно, это не null или undefined (поскольку вы бы получили другую ошибку). Итак, посмотрите на родительский компонент и определите, почему он будет передавать ненулевое, не неопределенное, не массивное значение в качестве comments prop.
  3. Одна часть, которая действительно остается для меня, - это ваша конечная точка API . Прямо сейчас, если files имеет значение null, 0, undefined, пустую строку или false, он будет отображаться как это значение JSON (что, вероятно, не то, что вы хотите). Если это неверно, вам, вероятно, следует вернуть код ошибки (возможно, 404), поскольку это предположительно означает, что ресурс на самом деле не существует.

К сожалению, контекста недостаточно для указывают на фактическую ошибку, и это вполне может быть комбинация вещей. Я бы рекомендовал либо добавить журналы консоли, либо использовать отладчик браузера для проверки как ответа, который вы получаете от сервера, так и тех значений, которые вызывают плохой доступ, прежде чем они будут использованы. Оттуда вам нужно будет работать в обратном направлении, чтобы определить, почему значения не соответствуют вашим ожиданиям.

...