#reactjs #redux
#reactjs #сокращение
Вопрос:
Простой для тех, у кого больше опыта в Redux, чем у меня. Я извлекаю некоторые локальные данные JSON, и Redux, похоже, не добавляет их в состояние. Консоль, регистрирующая массив в данных, выдает ‘undefined’.
INDEX.JS
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux'
import store from './components/store/store'
import App from './App';
import * as serviceWorker from './serviceWorker';
ReactDOM.render(
<Provider store={store()}>
<App />
</Provider>,
document.getElementById('root')
);
serviceWorker.unregister();
APP.JS
import React, { Component } from 'react'
import { connect } from 'react-redux'
import { BrowserRouter as Router, Route } from 'react-router-dom'
import { bindActionCreators } from 'redux' // new import, see below
import { addDataAction } from './components/actions/addDataAction'
etc...
// these cannot be const otherwise an error occurs
let mapStateToProps, mapDispatchToProps
class App extends Component {
componentDidMount(){
this.props.actions.addDataAction() // calling addData on mounting
}
render() {
return (
<Router>
<div className="App">
<div className="wrapper">
<Header />
<main>
{console.log(this.props.data.tshirts)}
</main>
</div>
<Footer />
</div>
</Router>
)
}
mapStateToProps = state => ({
data: state.data
})
mapDispatchToProps = dispatch => {
return {
actions: bindActionCreators({
addDataAction
}, dispatch)
}
}
export default connect(mapStateToProps, mapDispatchToProps)(App)
РЕДУКТОР — addDataReducer.js
const initialState = {
data: []
};
export default (state = initialState, action) => {
switch (action.type) {
case "ADD_JSON_DATA":
return {
...state, // returning state
data: action.data // updating the data
};
default:
return state;
}
};
СОХРАНИТЬ — store.js
import { createStore } from "redux"
import addDataReducer from "../reducers/addDataReducer"
function store() {
return createStore(addDataReducer)
}
export default store
Установленные зависимости:
"dependencies": {
"gulp": "^4.0.0",
"gulp-sass": "^4.0.2",
"gulp-util": "^3.0.8",
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-redux": "^7.0.2",
"react-router-dom": "^5.0.0",
"react-scripts": "2.1.8",
"redux": "^4.0.1",
"redux-devtools": "^3.5.0"
}
JSON:
{
"tshirts" : [
{
"id": 707860,
"brand": "Hamp;M",
"name": "T-Shirt",
"photo": "tshirt.jpg",
"colors": [
"red",
"blue",
"green",
"gray"
],
"sizes": [
"S",
"M",
"L",
"XL"
],
"price": 14,
"currency": "GBP"
},
{
"id": 43455,
"brand": "Topman",
"name": "The Tee Shirt",
"photo": "tshirt.jpg",
"colors": [
"red",
"blue",
"green",
"gray"
],
"sizes": [
"S",
"M",
"L",
"XL"
],
"price": 14,
"currency": "GBP"
}
],
"jumpers" : [
{
"id": 653655,
"brand": "Hamp;M",
"name": "The J Jumper",
"photo": "jumper.jpg",
"colors": [
"red",
"blue",
"green",
"gray"
],
"sizes": [
"S",
"M",
"L",
"XL"
],
"price": 24,
"currency": "GBP"
},
{
"id": 43455,
"brand": "Topman",
"name": "Une Jupe",
"photo": "jumper.jpg",
"colors": [
"red",
"blue",
"green",
"gray"
],
"sizes": [
"S",
"M",
"L",
"XL"
],
"price": 23,
"currency": "GBP"
}
],
"trousers" : [
{
"id": 645645,
"brand": "Next",
"name": "The Trow Sir",
"photo": "trousers.jpg",
"colors": [
"red",
"blue",
"green",
"gray"
],
"sizes": [
"S",
"M",
"L",
"XL"
],
"price": 24,
"currency": "GBP"
},
{
"id": 54555,
"brand": "Topman",
"name": "Une Trow",
"photo": "trousers.jpg",
"colors": [
"red",
"blue",
"green",
"gray"
],
"sizes": [
"S",
"M",
"L",
"XL"
],
"price": 23,
"currency": "GBP"
}
],
"jackets" : [
{
"id": 44344,
"brand": "Gap",
"name": "Gap Jacket",
"photo": "jacket.jpg",
"colors": [
"red",
"blue",
"green",
"gray"
],
"sizes": [
"S",
"M",
"L",
"XL"
],
"price": 24,
"currency": "GBP"
},
{
"id": 422542,
"brand": "Gap",
"name": "Their other jacket",
"photo": "jacket.jpg",
"colors": [
"red",
"blue",
"green",
"gray"
],
"sizes": [
"S",
"M",
"L",
"XL"
],
"price": 23,
"currency": "GBP"
}
],
"suits" : [
{
"id": 44344,
"brand": "Moss Bros",
"name": "The Three Piece",
"photo": "suit.jpeg",
"colors": [
"red",
"blue",
"green",
"gray"
],
"sizes": [
"S",
"M",
"L",
"XL"
],
"price": 24,
"currency": "GBP"
},
{
"id": 422542,
"brand": "Gap",
"name": "The Two Piece",
"photo": "suit.jpeg",
"colors": [
"red",
"blue",
"green",
"gray"
],
"sizes": [
"S",
"M",
"L",
"XL"
],
"price": 23,
"currency": "GBP"
}
]
}
Бла-бла-бла — Stackoverflow говорит, что я должен добавить больше текста.
Ответ №1:
Функция отправки ожидает объект в качестве аргумента, и вы передаете ему функцию.
Вам нужно отправить вызов действия, а не самого создателя действия (заменить dispatch(addDataAction)
на dispatch(addDataAction())
const mapDispatchToProps = dispatch => ({
addDataAction: () => dispatch(addDataAction())
})
Комментарии:
1. Спасибо за вашу помощь. К сожалению, реквизит футболки все еще не определен; (
Ответ №2:
РЕДУКТОР — addDataReducer.js
Укажите начальное состояние для редуктора:
const initialState = {
data: []
}
export default (state = initialState, action) => {
switch (action.type) {
case 'ADD_JSON_DATA':
return {
...state, // returning state
data: action.data // updating the data
}
default:
return state;
}
}
ДЕЙСТВИЕ — addDataAction.js
import clothesData from '../json/clothes.data.json'
export const addDataAction = () => { // transformed into a function
return {
type: 'ADD_JSON_DATA',
data: clothesData
}
}
СОХРАНИТЬ — store.js
import { createStore } from "redux"
import addDataReducer from "../reducers/addDataReducer"
function store() {
return createStore(addDataReducer)
}
export default store
APP.JS
import React, { Component } from 'react'
import { bindActionCreators } from 'redux' // new import, see below
import { connect } from 'react-redux'
import { BrowserRouter as Router, Route } from 'react-router-dom'
import { addDataAction } from './components/actions/addDataAction'
class App extends Component {
componentDidMount(){
this.props.actions.addDataAction() // calling addData on mounting
}
render() {
return (
<Router>
<div className="App">
<div className="wrapper">
<Header />
<main>
{console.log(this.props.data.tshirts)}
</main>
</div>
<Footer />
</div>
</Router>
)
}
}
const mapStateToProps = state => ({
data: state.data
})
const mapDispatchToProps = dispatch => {
return {
actions: bindActionCreators({
addDataAction
}, dispatch)
}
}
export default connect(mapStateToProps, mapDispatchToProps)(App);
Комментарии:
1. Спасибо за это. Я добавил ваши изменения, но получаю неожиданную ошибку токена со значением по умолчанию в инструкции export. Я также должен объявить переменные функции как глобальные, чтобы устранить ошибку с помощью const. Мне не нравится Redux ;/
2. экспортировать подключение по умолчанию (mapStateToProps, mapDispatchToProps) (приложение)
3. О! Моя ошибка, это «App.js » файл. Вы создали хранилище?
4. Я обновил фрагменты кода тем, что у меня есть. Ошибка «Ошибка синтаксического анализа: неожиданный токен» <— это относится к «умолчанию» инструкции export
5. Хранилище создается в store.js / createStore, верно?