Реагировать на редуксы не синхронизировать реквизиты в mapStateToProps - PullRequest
0 голосов
/ 12 февраля 2019

Я использую React redux с базой данных Firebase в реальном времени.В App.js я отправляю действие fetchAllPosts

App.js

class App extends Component {
  componentDidMount() {
    this.props.fetchAllPosts();
  }
  render() {
    return (
      <div className="App">
          // something ...
      </div>
    );
  }
}
const mapDispatchToProps = dispatch => {
  return {
      fetchAllPosts: () => {dispatch(allPosts())}
  }
}

Мое действие выглядит так (я использую избыточный-thunk):

действие

export function allPosts() {
    return (dispatch) => {  
firebase.database().ref('posts/').on('value', (snapshot) => {
        dispatch({type: "ALL_POSTS", postsArray: snapshot.val(), loading: false})
    })
    }
}

Тогда я комбинирую редукторы (я знаю, что в этом случае это не нужно):

const rootReducer = combineReducers({
    allPosts: postsReducer
})

Мой редукторвыглядит так:

редуктор

const initialState = {
    allPosts: []
}

const postsReducer = (state = initialState, action) => {
    switch(action.type) {
        case "ALL_POSTS" :
        console.log("action payload all posts", action.postsArray)
        return {
            ...state,
            loading: false,
            allPosts: action.postsArray
        }
        break;
        default:
        return state
    }
    return state
}

И наконец: мой компонент SinglePostview выглядит так: SinglePostview.js

import React, {Component} from 'react';
import {connect} from 'react-redux';

class SinglePostview extends Component {
    render() {
        console.log("ppp", this.props)
        return (
            <h2>{this.props.post.title}</h2>
        )
    }
}

const mapStateToProps = (state, ownprops) => {
    const postId = ownprops.match.params.postid
    return {
        post: state.allPosts.allPosts[postId]
    }
}

export default connect(mapStateToProps)(SinglePostview);

Здесь, когда выполняется метод рендеринга, this.props.post не определено, и у меня есть ошибка:

TypeError: Невозможно прочитать свойство 'title' из undefined.

Проблема в том, что: когда приложение загружается в первый раз, props.post не определено (поэтому у меня ошибка), и примерно через 1 секунду оно получает значение, но ничего не меняет - ошибка все еще существует, изначение не отображается.Кто-нибудь может мне помочь?

Ответы [ 2 ]

0 голосов
/ 12 февраля 2019

Если ваш редуктор в порядке, вы можете исправить это,

изменив это

render() {
        return (
            <h2>{this.props.post.title}</h2>
        )
    }

На это:

render() {
        if (!this.props.post){
            return null;
        }
        return (
            <h2>{this.props.post.title}</h2>
        )
    }

или

render() {
        return (
            <h2>{this.props.post && this.props.post.title}</h2>
        )
    }
0 голосов
/ 12 февраля 2019

Вы определяете allPosts как массив

    const initialState = {
    allPosts: []
    }

Но вы пытаетесь получить к нему доступ как к объекту.

state.allPosts.allPosts[postId]

Следовательно, если ваш state.allPosts.allPosts равенмассив, попробуйте использовать метод ES6 find (), чтобы получить сообщение из массива с идентификатором postId.

Предполагая

state.allPosts.allPosts = [
   {postId: 1,title:'abcd'},
   {postId:2,title:'def'}
]
 state.allPosts.allPosts.find(post => postId === post.postId)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...