TypeError: Невозможно прочитать свойство 'map' из неопределенного, используя ReactJs - PullRequest
0 голосов
/ 13 сентября 2018

Я получаю сообщение об ошибке «TypeError: Невозможно прочитать свойство« карта »из неопределенного». Не уверен, где я ошибаюсь. Я все еще довольно новичок, когда дело доходит до React, поэтому я не знаю, что я что-то упустил или нет. Это выдает ошибку, когда я пытаюсь вызвать this.props.meals.map

export class Dashboard extends React.Component {
  componentDidMount() {
    this.props.dispatch(fetchProtectedData());
    this.props.dispatch(retrieveDailyLogs())
    .then(results => {
        return this.props.dispatch(getDailyLogs(results));
    })
}

getId(id) {
   console.log('test');
   this.props.dispatch(removeDay(id))
   this.props.dispatch(retrieveDailyLogs())
  .then(results => {
    return this.props.dispatch(getDailyLogs(results));
});
}


render() {
    const dailyLogs = this.props.meals.map((day, index) => 
    <li className="card" key={index}>
        <Card handleClick={(id) => this.getId(id)} {...day} />
    </li>
    )
    return (
        <section className="dashboard-container">
            <h1>Dashboard</h1>
            <Link className="log-day-btn" to="/dailylogs">Log Meals</Link>
            <ul className="meal-list">
            {dailyLogs}
            </ul>
        </section>
    );
}
}

const mapStateToProps = state => ({
  meals: state.dailyLogsReducer.dailyLogs
});

export default requiresLogin()(connect(mapStateToProps)(Dashboard));

Вот мой редуктор на случай, если это поможет

import {ADD_DAY, GET_DAILYLOGS, DELETE_DAY} from '../actions/dailyLogs';

const initialState = {
 dailyLogs: [{
    date: null,
    meal1: null,
    meal2: null,
    meal3: null,
    snack: null,
    totalCalories: null,
}]
};

export default function reducer(state = initialState, action) {
 if (action.type === ADD_DAY) {
    return Object.assign({}, state, {
        dailyLogs: [...state.dailyLogs, {
            date: action.date,
            meal1: action.meal1,
            meal2: action.meal2,
            meal3: action.meal3,
            snack: action.snack,
            totalCalories: action.totalCalories
        }]
    });
}
else if(action.type === GET_DAILYLOGS) {
    return Object.assign({}, state, {
            dailyLogs: action.dailyLogs.dailyLogs
    })
}
else if(action.type === DELETE_DAY) {
    return 'STATE';
}
return state;
}

Вот мой комбайн редуктор. Это в моем магазине. Js

combineReducers({
    form: formReducer,
    auth: authReducer,
    protectedData: protectedDataReducer,
    dailyLogsReducer
}),

Ответы [ 2 ]

0 голосов
/ 13 сентября 2018

Поскольку вы объявили dailyLogs в initialState вашего редуктора как массив, ваша карта не должна давать сбой, а только ничего не показывает нам, если данные там есть.Если данные получены асинхронной операцией, вы не можете гарантировать, что эти данные будут там в момент рендеринга, выполненного React.

Итак, у нас есть несколько моментов:

Убедитесь, что вы выиграли 'я не получаю никаких ошибок, потому что вы пытались использовать неопределенную операцию с неопределенным значением:

const dailyLogs = this.props.meals  
console.log("meals =", dailyLogs); // Will help you know what is this value.
dailyLogs ? dailyLogs.map((day, index) => 
  <li className="card" key={index}>
    <Card handleClick={(id) => this.getId(id)} {...day} />
  </li> : // handle the non-mappable value ...
)

В вашем редукторе, как хорошая практика, попробуйте использовать оператор switch case, чтобы изучить его преимущества

switch (action.type) {
   case ADD_DAY: 
       return // ...
   case GET_DAILYLOGS:
       return // ...
   case DELETE_DAY: 
       return // ...
   default: 
       return state;
}

А в переключателе или при возврате операторов / else вы можете сделать следующее, чтобы развить состояние, сохраняя его атрибуты фактических данных (распространение):

return { 
    ...state, 
    dailyLogs: [
    // ...
    ]
};

Сохраняйте ваш код чище и лаконичнеепоможет вам вообще.

Надеюсь, это поможет каким-то образом.

0 голосов
/ 13 сентября 2018

Метод рендеринга может запускаться раньше, чем componentDidMount.Если this.props.meals еще не определено ко времени запуска метода рендеринга, ваш компонент выдаст ошибку, которую вы видите.

Вы можете проверить его наличие перед отображением объекта с помощью

this.props.meals && this.props.meals.map( // your code here )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...