gpt4 book ai didi

javascript - 使用 React-redux 中的 connect 时返回未定义的方法

转载 作者:行者123 更新时间:2023-12-03 00:55:44 26 4
gpt4 key购买 nike

每当用户单击按钮时,我都会尝试调用handleClick方法,但页面上不会呈现任何内容,并且收到错误“未捕获的ReferenceError:handleClick未定义”。

组件的实现:

import {createElement} from 'react';
import {add} from '../action/cart';
import {connect} from 'react-redux';
import styles from './styles.css';

handleClick = (id) => {
add(id);
this.setState((prevState) => ({
...prevState,
items: prevState.items.map(
(item) =>
id === item.id
? {id, quantity: item.quantity + 1}
: {...item}
),
}));
};

const Product = ({add, id, title, image}) => (
<div className={styles.product} onClick={handleClick(id)}>
<img src={image} alt={title} className={styles.productImage}/>
{title}
</div>
);

export default connect(() => ({}), {add})(Product);

这与购物车组件共享状态:

const Cart = connect(
() => ({}),
{clear}
)(({items, clear, total}) => {
return (
<div>
<Heading><FontAwesomeIcon icon={faShoppingCart} /> Cart</Heading>
{items.length ? <button onClick={clear}>Clear all items</button> : null}
<table>
<thead>
<tr>
<th>Product</th>
<th>Price</th>
<th>Quantity</th>
<th>Total</th>
</tr>
</thead>
<tbody>
{items.map(({...item}, id) => (
<Item {...item} key={id} />
))}
</tbody>
</table>
{items.length ?
<div className={styles.total}>${total}</div>
: <div>Your cart is empty!</div>}
</div>);
});

export default connect((state) => {
return {
items: state.cart.items,
total: reduce(
(sum, {id, quantity}) => sum + products[id].price * quantity,
0,
state.cart.items
).toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,'),
};
})(Cart);

它引用了此操作:

import {ADD_ITEM, SET_QUANTITY, CLEAR_ITEMS} from './types';
import {createAction} from 'redux-actions';

export const add = createAction(ADD_ITEM);
export const setQuantity = createAction(SET_QUANTITY);
export const clear = createAction(CLEAR_ITEMS);

哪个使用这个 reducer :

[ADD_ITEM]: (state, {payload: id}) => ({
...state,
items: [
...state.items,
{id, quantity: 1},
],
}),

最佳答案

您正在为 Product 创建一个无状态组件,并且 this 不应该在无状态组件内部使用(更不用说 setState code> 来自其处理程序)。相反,您应该使 Product 成为常规组件,如下所示:

编辑(删除以前的代码)

好的,我看到您已经更新了帖子中的代码。因此,这里有一些可能会让您困惑的事情:

如果您还没有这样做,请删除 handleClick 中的 setState。该逻辑应该位于 redux 操作内部,因为您的所有状态似乎都位于 redux 状态树中。

您为 Cart 调用 connect 两次。删除第一个调用,其中:

const Cart = connect(
() => ({}),
{clear}
)(({items, clear, total}) => {

应该变成:

const Cart = ({items, clear, total}) => {

我想你的意思是这个......

<tbody>
{items.map(({...item}, id) => (
<Item {...item} key={id} />
))}
</tbody>

...就是这样(我假设 products 存在于您的代码库中的某个位置,因为您在 Cartconnect 调用中使用了它>):

<tbody>
{items.map(({...item}, id) => (
<Product {...products[id]} {...item} key={id} />
))}
</tbody>

我认为你的意思是:

{
total: reduce(
(sum, {id, quantity}) => sum + products[id].price * quantity,
0,
state.cart.items
).toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,'),
}

是这样的:

{
total: state.cart.items.reduce(
(sum, {id, quantity}) => sum + products[id].price * quantity,
0,
).toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,'),
}

然后您需要将已删除的 connect 调用中的 clear 属性添加回剩余的调用中,留下:

export default connect(
state => ({
items: state.cart.items,
total: state.cart.items.reduce(
(sum, {id, quantity}) => sum + products[id].price * quantity,
0,
).toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,'),
}),
{clear},
)(Cart);

要返回到之前删除的 setStateADD_ITEM 的 reducer 可能应类似于以下内容:

[ADD_ITEM]: (state, {payload: id}) => {
const itemAlreadyInCart = state.items.find(i => i.id === id);
if (itemAlreadyInCart) {
return {
...state,
items: state.items.map(
(item) =>
id === item.id
? {id, quantity: item.quantity + 1}
: {...item}
),
}
}
else {
return {
...state,
items: [
...state.items,
{id, quantity: 1, },
],
}
}
},

我认为上述所有内容应该让您非常接近一切工作。

编辑2

回答您的评论,是否是因为您没有在 reducer 中处理 CLEAR_ITEMS 操作?也许您需要 reducer 看起来像这样?

[ADD_ITEM]: (state, {payload: id}) => {
const itemAlreadyInCart = state.items.find(i => i.id === id);
if (itemAlreadyInCart) {
return {
...state,
items: state.items.map(
(item) =>
id === item.id
? {id, quantity: item.quantity + 1}
: {...item}
),
}
}
else {
return {
...state,
items: [
...state.items,
{id, quantity: 1, },
],
}
}
},

[CLEAR_ITEMS]: (state) => {
return {
...state,
items: [],
}
},

顺便说一句,我还注意到另一个问题。我之前发布了此更改:

<tbody>
{items.map(({...item}, id) => (
<Product {...products[id]} {...item} key={id} />
))}
</tbody>

但是 map(({...item}, id) 中的 id 不是项目的 id 键,而是提供的数组的索引通过 map 函数。您可能想做这样的事情:

<tbody>
{items.map(({id, ...item}) => (
<Product {...products[id], ...item, id} key={id} />
))}
</tbody>

关于javascript - 使用 React-redux 中的 connect 时返回未定义的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52846759/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com