简体   繁体   English

React + Redux - 在哑组件中调度动作?

[英]React + Redux - dispatching an action in dumb component?

I started learning Redux and the whole idea looks neat, but after rebuilding my React app from "normal" to "redux-way" this problem came up. 我开始学习Redux并且整个想法看起来很整洁,但是在将我的React应用程序从“正常”重建为“redux-way”之后,出现了这个问题。

I have a list of if items that I build based on JSON from async call. 我有一个列表,列出了我基于异步调用的JSON构建的项目。 Then every item on that list sends an async call on click and returns something. 然后该列表上的每个项目都会在点击时发送异步调用并返回一些内容。

Before my app was pretty straightforward: 在我的应用程序非常简单之前:

components/list/List.jsx
components/list/ListItem.jsx

Right now it looks like this: 现在它看起来像这样:

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>

It's much more complicated IMO, but there's another problem. IMO要复杂得多,但还有另外一个问题。

Every time I click on my <li> component I want to trigger an action and then do something, my question is: can I do that in ListItem.jsx? 每次我点击我的<li>组件我想触发一个动作然后做一些事情,我的问题是:我可以在ListItem.jsx中做到吗? I don't think so, because it's a dumb component? 我不这么认为,因为它是一个愚蠢的组成部分?

Here's my ListItem.jsx right now: 这是我的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;

Just pass the click handler down to your dumb components. 只需将点击处理程序传递给您的哑组件即可。 A dumb component is just a component that doesn't care about the source of the props that it gets. 愚蠢的组件只是一个不关心它获得的道具来源的组件。 This doesn't mean it can't call functions or anything. 这并不意味着它不能调用函数或任何东西。 The reason we split them up this way is so that we can re-use dumb components elsewhere that get the props from a different source. 我们以这种方式将它们拆分的原因是我们可以在其他地方重复使用从不同来源获取道具的哑组件。

@bennygenel answer was mostly fine so I don't know why he deleted it. @bennygenel答案大部分时间都很好,所以我不知道他为什么删除它。

Here's what i'd do: 这是我要做的:

ListItem.js: 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: 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);

We bind the onClick handler in mapDispatchToProps, this automatically wraps the handler in a dispatch so that when the user clicks on the list item it dispatches properly. 我们在mapDispatchToProps中绑定onClick处理程序,这会自动将处理程序包装在一个调度中,这样当用户单击列表项时它会正确调度。

You aren't forced to split it up if you don't want to or don't see the need but now we can re-use ListItem for other click handlers because it's not tied to dispatching a specific action and props.content isn't tied to a specific state because we split that out into the container too. 如果你不想或不想看到需要,你不会被迫拆分它,但现在我们可以将ListItem重新用于其他点击处理程序,因为它不依赖于调度特定的动作而props.content isn'因为我们将其分解到容器中,所以它与特定的状态相关联。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM