Я только начал работать с Redux и пытался реализовать простое приложение MERN (для практики). Все в моем коде работает нормально, но моя функция редуктора показывает неожиданное поведение. Когда вызывается действие (которое получает данные из экспресс-api), мой редуктор правильно переходит к конкретным журналам данных случая переключения, но затем три раза передается случай по умолчанию, и данные на моем компоненте, которые я регистрирую, показывают null. Пожалуйста помоги. Вот мой код: -
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import { BrowserRouter as Router } from 'react-router-dom';
import { Provider } from 'react-redux';
import thunk from 'redux-thunk';
import { createStore, applyMiddleware, combineReducers } from 'redux';
import articlesReducer from './store/reducers/articlesReducer';
import registerServiceWorker from './registerServiceWorker';
const rootReducer = combineReducers({
articles: articlesReducer
});
const store = createStore(rootReducer, applyMiddleware(thunk));
const app = (
<Provider store = {store}>
<Router>
<App />
</Router>
</Provider>
);
ReactDOM.render(app, document.getElementById('root'));
registerServiceWorker();
App.js
import React, {Component} from 'react';
import {Switch, Route} from 'react-router-dom';
import './App.css';
import Home from './components/Home/Home';
class App extends Component {
render() {
return (
<div>
<Switch>
<Route exact path = "/" component = {Home} />
</Switch>
</div>
);
}
}
export default App;
article.js
export const getAllArticles = () => {
return dispatch => {
return (
fetch('http://localhost:5000/api/articles')
.then(res => res.json())
.then(data => {
dispatch({type: 'GET_ALL_ARTICLES', articles: data})
})
);
};
};
articleReducer.js
const initialState = {
articles:null
};
const reducer = (state = initialState, action) => {
switch (action.type) {
case 'GET_ALL_ARTICLES':
console.info('in reducer', action.type, action.articles[0]);
return {
...state,
articles: action.articles
};
default:
console.info('In default');
return state;
}
};
export default reducer;
myComponent
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { getAllArticles } from '../../store/actions/articles.js';
class MainPage extends Component {
componentWillMount() {
this.props.initArticles();
console.info(this.props.articles);
}
render() {
return (
<div className = "container">
<br />
<h1>Here comes the articles!!</h1>
</div>
);
}
}
const mapStateToProps = state => {
return {
articles: state.articles
};
};
const mapDispatchToProps = dispatch => {
return {
initArticles: () => dispatch(getAllArticles())
};
};
export default connect(mapStateToProps, mapDispatchToProps)(MainPage);
Вывод на моей консоли выглядит примерно так: -
In default
In default
In default
{articles: null}
in reducer GET_ALL_ARTICLES {articles[0] Object}
Не знаю, в чем ошибка. Заранее благодарим за помощь.
Мне очень жаль, но я не знаю, откуда взялась ошибка, она в основном связана с моей частью редуктора, и я предполагаю, что в моем компоненте (хотя и не уверен), actions.js отлично отправляет данные в редуктор.
Я действительно понимаю, что код довольно большой. Но если уж их увидеть, то они просто небольшие фрагменты и четко понятны. Я был бы очень признателен, если бы вы могли попробовать.
Думаю, твои статьи есть в state.articles.articles. Первый, потому что он находится в редукторе статей, второй - в редукторе статей, это поле статей.
Данные в моем редукторе достигают должным образом, но не до компонента и трижды «По умолчанию» в выводе на консоли.
@Ursus, я тоже пробовал, но потом в консоли показывает null вместо {articles: null}.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Я не уверен, действительно ли это проблема, но вы неправильно обращаетесь к articles. У вас есть корневой редуктор с редуктором articles:
const rootReducer = combineReducers({
articles: articlesReducer
});
какое начальное состояние:
const initialState = {
articles:null
};
И в вашем mapDispatchToProps вы "импортируете" все состояние редуктора:
const mapStateToProps = state => {
return {
articles: state.articles
};
};
Я думаю, вы хотели получить доступ к свойству articles
const mapStateToProps = state => {
return {
articles: state.articles.articles
};
};
В остальном вроде все в порядке. Однако, как указано в комментарии, я бы инициализировал articles как пустой массив [].
const initialState = {
articles: []
};
ага, тоже лучше поставить const initialState = [];
@Tomasz Mularczyk Я все перепробовал, теперь выдает ошибку, что TypeError: Cannot read property 'articles' of undefined на articles: state.articles.articles
Кроме того, я не понимаю, почему я получаю три In default, а затем правильный / ожидаемый результат in reducer ....
Эй, вернемся с небольшим обновлением после упомянутых вами изменений ... Я получаю свои данные в componentWillReceiveProps() и методом render(). И, таким образом, я могу отобразить его на своей странице. Благодаря тонну!! @Tomasz Mularczyk :-) Извините, если я отнял у вас много времени
Слишком много кода, не могли бы вы попытаться изолировать ошибочное поведение, пожалуйста?