Redux和React。未捕获的TypeError:无法读取属性' dispatch'未定义的

时间:2017-05-01 20:38:06

标签: javascript reactjs redux connect dispatch

我试图从深层嵌套的组件调用dispatch。 我正在使用Redux和React。

我的应用结构是:

[应用]

---- [主要]

-------- [ShopCoffee]

-------- [其他组件]

当我致电'发送'来自app.jsx它有效。

当我致电'发送'它从主要组件工作,当我从render()方法调用dispatch时(它有警告,但仍然有效),但是当我调用' dispatch'时,它不起作用。来自其他地方。

我使用Provider和addNewItemToCart()作为道具传递商店,但是当我从ShopCoffee组件调用addNewItemToCart时,出现错误: " Uncaught TypeError:无法读取属性' dispatch'未定义"

这是我的计划:

App.jsx



import React from "react";
import ReactDOM from "react-dom";

import Main from "./components/main.component.jsx";
import { createStore } from "redux";
import { Provider } from "react-redux";

var app = document.getElementById("app");

function mainAppReducer(state, action) {
	if (!state) return {
		text: 'test text 1231'
	}
	switch (action.type) {
		case 'ADD_TO_CART' : console.log('ADD_TO_CART');
		return Object.assign({}, state, { text : action.text });
	}
}
const store = createStore(mainAppReducer);

store.dispatch ({
	type : 'ADD_TO_CART',
	text : 'One more message! ;)'
});

store.dispatch ({
	type : 'ADD_TO_CART',
	text : 'Text text message from redux! ;)'
});

console.log("store.getState() == ", store.getState());

var render = () => ReactDOM.render(<Provider store={store}><Main /></Provider>, app);
store.subscribe(render);
render();

console.log("store.getState() == ", store.getState());
&#13;
&#13;
&#13;

main.component.jsx

&#13;
&#13;
import React from "react";
import Header from "./header.component.jsx";
import Footer from "./footer.component.jsx";
import Cart from "./cart.component.jsx";
import Checkout from "./checkout.component.jsx";
import ShopCoffee from "./shop-coffee.component.jsx";
import Rent from "./rent.component.jsx";
import Repair from "./repair.component.jsx";
import Contacts from "./contacts.component.jsx";
import { connect } from "react-redux";

export class Main extends React.Component {
	constructor(props) {
		super(props);
	}
	addNewItemToCart(itemsInCart) {
		console.log("works");
		console.log("addNewItemToCart() :: itemData == ", itemsInCart);		
		console.log("from Main: this.props", this.props);
		this.props.dispatch({type : 'ADD_TO_CART'});
	
	}

	getItemsInCart(itemsInCart) {
		console.log("getItemsInCart() :: itemData == ", itemsInCart);
		return itemsInCart;
	}

	render() {
		console.log('(from render) this.props == ', this.props);
		console.log('dispatch==', this.props.dispatch);
		
		return (
			<main>
				<Header />
				<Cart getItemsInCart = {this.getItemsInCart} />
				<Checkout />
				<ShopCoffee addNewItemToCart = {this.addNewItemToCart}/>
				<Rent />
				<Repair />
				<Contacts />				
				<Footer />
			</main>
		);
	}
}

export default connect((store) => store)(Main);
&#13;
&#13;
&#13;

shop-coffee.component.jsx

&#13;
&#13;
import React from "react";

export default class ShopCoffee extends React.Component {
	constructor(props) {
		super(props);
		console.log("ShopCoffee /constructor()");
		console.log("ShopCoffee / this.props", this.props);
		this.state = {shopItems : [], itemsInCart : []};
	}

// =============== Добавляет выбранный товар в корзину ===============
	addItemToCart(i) {
		console.log("addItemToCart() i == ",i);
		console.log("addItemToCart() :: this.props", this.props);
		let newSelectedItem = this.state.shopItems[i];
		this.state.itemsInCart.push(newSelectedItem);
		this.props.addNewItemToCart(this.state.itemsInCart);


	}

	getData() {
		const url="/data/coffee.json";
		fetch(url)
			.then((resp) => resp.json())
			.then((data) => {
				this.state.shopItems = data;
			})
		.catch((error) => console.error("Ошибка загрузки данных из файла", url));
		
	}


	componentWillMount() {
		this.getData();
	}
	 componentDidMount() {
        setInterval(() => this.setState(this.state), 1000);
    }

	render() {
		var itemsArr = [];
		var itemsRow = [];

		//console.log("this.state.shopItems ===", this.state.shopItems);
		for (let i=0; i < this.state.shopItems.length; i++) {

			let item = this.state.shopItems[i];

			
			itemsArr.push(
							<div className="shop-coffee__item" key={"item"+i}> 
								<div className="shop-coffee__item__inner">
									<div className="row">
										<div className="shop-coffee__item__kg">
											<p className="shop-coffee__item__kg__text">{item.weight}</p>
										</div>
										<div className="shop-coffee__item__space">
										</div>
										<div className="shop-coffee__item__price">
											<p className="shop-coffee__item__price__text">{item.price}</p>
										</div>	
									</div>	
									<div className="row">												
										<div className="shop-coffee__item__image">
											<img className="shop-coffee__item__image__img" src="img/template-img__coffee-shop.jpg" />
										</div>
									</div>
									<div className="row">
										<div className="shop-coffee__item__description">
											<p className="shop-coffee__item__description__text">
												{item.title}
											</p>
											<p className="shop-coffee__item__description__text">
												{item.description}
											</p>
										</div>
									</div>
									<div className="row">
										<div className="shop-coffee__item__button-container">
											<button className="shop-coffee__item__button-container__button" onClick={this.addItemToCart.bind(this, i)}>
												Заказать
											</button>
										</div>
									</div>
								</div>
							</div> 
			);
			
			if ( ((i>0) && (i%3 == 0)) || (i == this.state.shopItems.length-1)) {
				itemsRow.push(
							<div className="row" key={"row"+i}>
								{itemsArr}
							</div>);
				itemsArr = [];

			}

		}
		return (
				<section className="shop-coffee">
					<div className="container">
						<div className="row">
							<div className="shop-coffee__title-container">
								<h2 className="shop-coffee__title-container__title">
									Магазин кофе
								</h2>
							</div>
						</div>

				
							{itemsRow}

						
					</div>
				</section>
		);
	}
}
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:1)

我认为你缺少绑定到类实例的回调,在组件的构造函数中如下:

constructor(props) {
    super(props);
    ...
    this.addNewItemToCart = this.addNewItemToCart.bind(this);
}

基本上:如果使用ES6类,则需要绑定回调函数 有关详细信息,请参阅React docs:

https://facebook.github.io/react/docs/handling-events.html