如何将动作传递给 redux 中的组件
Posted
技术标签:
【中文标题】如何将动作传递给 redux 中的组件【英文标题】:How to pass actions down to the components in redux 【发布时间】:2017-04-05 15:41:40 【问题描述】:我想在我的组件中触发一个动作。这是一个表示组件,不需要了解 redux。路由器实现是使用 react-router-redux 完成的。
main.js:
let store = createStore(rootReducer)
const history = syncHistoryWithStore(hashHistory, store)
class RenderClass extends Component
render()
return (
<Provider store=store>
<Router history=history>
<Route path="/" component=MainLayout>
<Route name="employees" path="/employees" url="http://localhost:8080/" component=EmployeeTable></Route>
<Route name="personalInformation" path="/personalInformation/:employeeId" url=URI component=PersonalInformation />
.....
</Route>
<Router>
</Provider>
);
App.jsx:
import * as Actions from './action-creator';
const MainLayout = React.createClass(
render: function()
const dispatch, list = this.props;
let actions = bindActionCreators(Actions, dispatch);
console.log(actions);
return (
<div className="wrapper">
<Header actions=actions list=list params=this.props.params />
React.cloneElement(this.props.children, this.props)
</div>
)
);
function select(state)
return
list: state.listingReducer
export default connect(select)(MainLayout);
header.js:
define(
[
'react',
'jquery',
'appMin'
],
function (React, $)
var Link = require('reactRouter').Link;
var Header = React.createClass(
handleClick: function ()
//Action called here
this.props.actions.listEmployees();
,
render: function ()
return (
<ul className="sidebar-menu">
<li>
<Link to='/employees' onClick=this.handleClick><i className="fa fa-home"></i>Employees</Link>
</li>
</ul>
);
);
return Header;
)
employee.js:
define(
[
'react',
'jquery',
'appMin'
],
function (React, $)
var EmployeeTable = React.createClass(
render: function ()
if (this.props.list != undefined)
var listItems = this.props.list.map(function (listItem)
return (
<tr key=listItem.id>
<td> listItem.name</td>
<td><Link to='/personalInformation/' + employee.id onClick=this.props.actions.displayPersonalInformation(employee.id)>Personal Information</Link></td>
......
</tr>
);
, this);
)
return (
<table>
<tbody>
listItems
</tbody>
</table>
);
)
)
action-creator.js:
export function listEmployees()
return
type: types.LIST_EMPLOYEES
;
export function displayPersonalInformation()
return
type: types.DISPLAY_PERSONAL_INFORMATION
;
reducer.js:
function addEmployee(state, action)
switch (action.type)
case types.LIST_EMPLOYEES:
return "id":"1", "name":"***"
default:
return state
function listingReducer(state = [], action)
switch (action.type)
case types.LIST_EMPLOYEES:
return [
...state,
addEmployee(undefined, action)
]
case types.DISPLAY_PERSONAL_INFORMATION:
return // Gets personal Information
default:
return state;
const rootReducer = combineReducers(
listingReducer
)
export default rootReducer
道具不会包含动作,因为我没有将它绑定到道具。我尝试在 App.js 中编写 mapStateToProps 和 mapDispatchToProps 如下所示:
function mapStateToProps(state)
return
list: state.list
function mapDispatchToProps(dispatch)
return actions: bindActionCreators( actionCreators , dispatch)
导出默认连接(mapStateToProps, mapDispatchToProps)(MainLayout) 我收到调度不是功能错误。错误语句实际上听起来像是***中的重复问题,但我也想知道我使用mapDispatchToProps的目的也是正确的。提前致谢。
【问题讨论】:
您在哪个部分 od 代码上收到此错误? @JaganathanBantheswaran:我在 mapDispatchToProps 函数中以及在触发操作后收到此错误。除了错误,我想知道当我应该在使用 redux 路由器时在表示组件中使用操作时我应该做什么。 【参考方案1】:据我了解,您正在使用export default connect(mapStateToProps, mapDispatchToProps)(MainLayout)
并尝试在MainLayout
中调用dispatch
。
所以从 react-redux 文档中,如果你看到你可以通过以下方式调用 connect:-
connect()(//Component)
--> dispatch 将作为 props 传递
connect(mapStateToProps)(//Component)
--> dispatch 将作为 props 传递
connect(mapStateToProps,mapDispatchToProps)(//Component)
--> dispatch 不会作为 props 传递给您的组件
在场景 3 中,这种行为是这样的,因为 mapDispatchToProps
已经可以访问调度函数。所以你可以绑定你的函数以在mapDispatchToProps
中调度,然后将此函数传递给你的组件。
示例
您要调度的函数是dispatchMe()
和dispatchMe2()
,它们调用了一个名为dispatchAction
的操作。所以你的mapDispatchToProps
会是这样的:-
function mapDispatchToProps(dispatch)
return
dispatchMe : () =>
dispatch(dispatchAction())
,
dispatchMe2 : () =>
dispatch(dispatchAction2())
现在您可以在您的组件中传递dispatchMe
并在需要时调用它。
您可以阅读here 了解更多信息
【讨论】:
感谢您的回复。基本上我会在我的 Employee 组件中使用动作“displayPersonalInformation”,它是一个表示组件,因此不支持 redux。为此,您建议我将其条目放入 mapDispatchToProps(如您所示)并可以访问它。现在我试图让它通用。如果我想在演示组件中使用任何动作,那么我必须在我的 mapDispatchToProps 中有那个动作条目。如果我错了,请纠正我。 是的,应该这样做。理想情况下,您应该创建一个EmployeeContainer
并将mapDispatchToProps
作为道具从您的容器传递给您的Employee
组件。
那么 mapDispatchToProps 的外观如何?因为我将有一组可能在该组件中使用的动作创建器。每个动作创建者在 mapDispatchToProps 中有一个单独的条目吗?再次总结一下,“bindActionCreators”永远不会在 mapDispatchToProps 中使用。
@Harikirat,在将 mapDispatchToProps 放入我的连接函数后,我仍然在 bindActionCreators.js 文件中收到错误“显示不是函数”。
你能分享你的代码一次吗?我正在更新多个调度操作的答案【参考方案2】:
由于您使用了bindActionCreators
,所以redux
将在您调用动作创建者时dispatch
动作,即在您的情况下为displayPersonalInformation
。
正如@Harkirat Saluja 在他的回答中提到的那样,如果您使用了mapDispatchToProps
,那么您的组件将不会具有与props
绑定的dispatch
函数。
但是,如果您想同时拥有 dispatch
和 props
(不是最佳实践),那么您可以拥有类似的东西,
function mapDispatchToProps(dispatch)
return dispatch, ...actions: bindActionCreators( actionCreators , dispatch)
【讨论】:
感谢您的回复。我可以在 redux 中完全不将我的行为与道具联系起来吗?因为那是我的核心问题。如果我听起来很傻,请原谅我。 按照 Harikirat 所说,将 mapDispatchToProps 放入我的连接函数后,我仍然在 bindActionCreators.js 文件中收到错误“显示不是函数”。 当您已经在 mapDispatchToProps 中拥有绑定调度道具时,我无法理解您为什么要绑定调度道具。 @HarkiratSaluja 如果你想拥有dispatch
和props
的功能(不是最佳实践),那么你可以像我展示的那样拥有它。仔细阅读我的答案
@Harkirat:对,我不需要。【参考方案3】:
class MainLayout extends React.component
render()
console.log(this.props.list);
return(
<div>
<h1>mainlayout</h1>
</div>
);
function mapStateToProps(state)
return
list: state.listingReducer
export default connect(mapStateToProps)(MainLayout);
【讨论】:
【参考方案4】:您无法通过道具访问您的操作,因为您将操作分配给操作属性。将动作绑定到道具的方式可以通过 this.props.actions.myFunction 访问函数。如果你想直接通过 props 调用你的 action,像这样将你的 action 连接到你的 props:
const mapDispatchToProps = (dispatch) =>
return bindActionCreators(actionCreators, dispatch);
;
export default connect(null, mapDispatchToProps)(MainLayout);
【讨论】:
【参考方案5】:import bindActionCreators, from 'redux';
import connect, from 'react-redux';
/**
* Map redux actions to the Component's props
* @param * dispatch The Redux store's dispatch method
* @returns * Object
*/
const mapDispatchToProps = (dispatch) =>
return bindActionCreators(
yourActions,
, dispatch);
;
export default connect(mapDispatchToProps)(MainLayout);
【讨论】:
以上是关于如何将动作传递给 redux 中的组件的主要内容,如果未能解决你的问题,请参考以下文章