React + Redux - 在哑组件中调度一个动作?
React + Redux - dispatching an action in dumb component?
我开始学习 Redux,整个想法看起来很简洁,但是在将我的 React 应用程序从 "normal" 重建到 "redux-way" 之后,这个问题出现了。
我有一个 if 项目列表,这些项目是我基于来自异步调用的 JSON 构建的。然后该列表中的每个项目都会在点击时发送一个异步调用和 returns 东西。
在我的应用程序非常简单之前:
components/list/List.jsx
components/list/ListItem.jsx
现在看起来像这样:
footer/list/ListContainer.jsx // here I run an async call and generate list
footer/list/List.jsx // dumb component creating the whole list full of ListItemContainer components as <li>
footer/list/ListItemContainer.jsx // here I run another async for each <li>
footer/list/ListItem.jsx // dumb component containing <li>
IMO 要复杂得多,但还有另一个问题。
每次我点击我的 <li>
组件我想触发一个动作然后做一些事情,我的问题是:我可以在 ListItem.jsx 中做到吗?我不这么认为,因为它是一个愚蠢的组件?
这是我现在的 ListItem.jsx:
import React from 'react';
import { connect } from 'react-redux';
// some other imports
class ListItem extends React.Component {
render(props) {
return (
<li>
<a href="#" onClick={//can I do something here?//}>
{this.props.contents}
</a>
</li>
)
}
}
export default ListItem;
只需将点击处理程序传递给您的哑组件即可。一个愚蠢的组件只是一个不关心它获得的道具来源的组件。这并不意味着它不能调用函数或任何东西。我们以这种方式拆分它们的原因是我们可以在其他地方重新使用哑组件,从不同的来源获取道具。
@bennygenel 的回答基本没问题,所以我不知道他为什么删除它。
我会这样做:
ListItem.js:
// Dumb component (very re-usable)
const ListItem = props => (
<li>
<a href="#" onClick={props.onClick}>
{props.contents}
</a>
</li>
);
export default ListItem;
ListItemContainer.js:
// Smart component
import action from 'someAction';
const mapStateToProps = (state) => ({
contents: state.something.contents,
});
const mapDispatchToProps = {
onClick: action,
};
export default connect(mapStateToProps, mapDispatchToProps)(ListItem);
我们在 mapDispatchToProps 中绑定 onClick
处理程序,这会自动将处理程序包装在调度中,以便当用户单击列表项时它会正确调度。
如果您不想或看不到需要,您不会被迫拆分它,但现在我们可以将 ListItem
重新用于其他点击处理程序,因为它与调度无关一个特定的动作并且 props.content
不依赖于一个特定的状态,因为我们也将其拆分到容器中。
我开始学习 Redux,整个想法看起来很简洁,但是在将我的 React 应用程序从 "normal" 重建到 "redux-way" 之后,这个问题出现了。
我有一个 if 项目列表,这些项目是我基于来自异步调用的 JSON 构建的。然后该列表中的每个项目都会在点击时发送一个异步调用和 returns 东西。
在我的应用程序非常简单之前:
components/list/List.jsx
components/list/ListItem.jsx
现在看起来像这样:
footer/list/ListContainer.jsx // here I run an async call and generate list
footer/list/List.jsx // dumb component creating the whole list full of ListItemContainer components as <li>
footer/list/ListItemContainer.jsx // here I run another async for each <li>
footer/list/ListItem.jsx // dumb component containing <li>
IMO 要复杂得多,但还有另一个问题。
每次我点击我的 <li>
组件我想触发一个动作然后做一些事情,我的问题是:我可以在 ListItem.jsx 中做到吗?我不这么认为,因为它是一个愚蠢的组件?
这是我现在的 ListItem.jsx:
import React from 'react';
import { connect } from 'react-redux';
// some other imports
class ListItem extends React.Component {
render(props) {
return (
<li>
<a href="#" onClick={//can I do something here?//}>
{this.props.contents}
</a>
</li>
)
}
}
export default ListItem;
只需将点击处理程序传递给您的哑组件即可。一个愚蠢的组件只是一个不关心它获得的道具来源的组件。这并不意味着它不能调用函数或任何东西。我们以这种方式拆分它们的原因是我们可以在其他地方重新使用哑组件,从不同的来源获取道具。
@bennygenel 的回答基本没问题,所以我不知道他为什么删除它。
我会这样做:
ListItem.js:
// Dumb component (very re-usable)
const ListItem = props => (
<li>
<a href="#" onClick={props.onClick}>
{props.contents}
</a>
</li>
);
export default ListItem;
ListItemContainer.js:
// Smart component
import action from 'someAction';
const mapStateToProps = (state) => ({
contents: state.something.contents,
});
const mapDispatchToProps = {
onClick: action,
};
export default connect(mapStateToProps, mapDispatchToProps)(ListItem);
我们在 mapDispatchToProps 中绑定 onClick
处理程序,这会自动将处理程序包装在调度中,以便当用户单击列表项时它会正确调度。
如果您不想或看不到需要,您不会被迫拆分它,但现在我们可以将 ListItem
重新用于其他点击处理程序,因为它与调度无关一个特定的动作并且 props.content
不依赖于一个特定的状态,因为我们也将其拆分到容器中。