React + Redux - dispatching an action in dumb component?

家住魔仙堡 提交于 2020-02-24 10:53:28

问题


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.

I have a list of if items that I build based on JSON from async call. 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.

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? I don't think so, because it's a dumb component?

Here's my ListItem.jsx right now:

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;

回答1:


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.

Here's what i'd do:

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);

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.

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.



来源:https://stackoverflow.com/questions/47120630/react-redux-dispatching-an-action-in-dumb-component

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!