ReactJS + Redux:如何将动作创建者构建到每个组件?

Jo *_* Ko 15 javascript reactjs react-jsx redux

我有一个名为的父组件App.js:

...

render() {
  return (
    <div>
      {React.cloneElement(this.props.children, this.props}
    </div>
  )
}

...

function mapDispatchToProps(dispatch) {
  return (
    actions: bindActionCreators(actions, 
  )
}

export default connect(
  ...,
  mapDispatchToProps
)(App)
Run Code Online (Sandbox Code Playgroud)

道具将传递给每个组件.我想让每个组件都有自己的动作创建者文件,但是如何将所有动作创建者绑定到一个组件中,以便动作创建者可以从该App.js级别传递下去?任何其他建议也将受到赞赏,以便将动作创建者分解为每个组件.

这是迄今为止的结构:

ComponentOne
..actions.js //action creators
..ComponentOne.js
ComponentTwo
..actions.js //action creators
..ComponentTwo.js
App.js
actions.js//should I compile all the action creators here?
Run Code Online (Sandbox Code Playgroud)

每个人actions.js都会这样做:

let actions = {
  logSayings() {
    ...
  }
}

export default actions
Run Code Online (Sandbox Code Playgroud)

提前谢谢你,并将upvote /接受答复.

REDUX设置

store.js

import { applyMiddleware, compose, createStore } from 'redux'
import rootReducer from './reducers/rootReducer'
import logger from 'redux-logger'
import thunk from 'redux-thunk'

let finalCreateStore = compose(
  applyMiddleware(thunk, logger())
)(createStore)

export default function configureStore(initialState = {articles: []}) {
  return finalCreateStore(rootReducer, initialState)
}
Run Code Online (Sandbox Code Playgroud)

actions.js

import { hashHistory } from 'react-router'
import { browserHistory } from 'react-router';

let actions = {
  updateBar(status) {
    return {
      type: 'UPDATE_BAR',
      indicator: status
    }
  }
}

export default actions
Run Code Online (Sandbox Code Playgroud)

homeReducer.js

const homeReducer = function(articles = [], action){
  switch(action.type){
    case 'UPDATE_BAR':
      return {
        indicator: action.indicator,
      }

    default:
      return articles
  }
}

export default homeReducer
Run Code Online (Sandbox Code Playgroud)

index.js

import React from 'react';
import {render} from 'react-dom';
import configureStore from '../../redux/store'
import { Provider } from 'react-redux'
import { Router, Route, IndexRoute, hashHistory } from 'react-router'

import App from './components/App'
import Home from './components/Home/Home'

let initialState = {

}

let store = configureStore(initialState)

render(
  <div>
    <Provider store={store}>
      <Router history={hashHistory}>
        <Route
          component={App}
          path='/'
        >
          <IndexRoute component={Home}/>
        </Route>
      </Router>
    </Provider>
  </div>,
  document.querySelector('.wrapper')
)
Run Code Online (Sandbox Code Playgroud)

小智 6

这是我通常构建我的react/redux应用程序的方式.

我在组件和容器之外保留操作.我通常会尝试将我的操作文件命名为特定于我正在构建的应用程序区域.例如,UsersActions,ProductActions,OrdersActions,CheeseActions也有效......

App
  actions
    CheeseActions.js
    ...
  components
    CheeseBox.js
  containers
    CheeseApp.js
  ...
Run Code Online (Sandbox Code Playgroud)

示例容器 - 让容器处理操作.(有点像控制器.)

// import the actions that this container needs to do it's job.
import { makeCheese, sellCheese } from '../actions/CheeseActions'
import CheeseBox from '../components/CheeseBox'

class CheeseApp extends Component {

  // Let the container handle the actions
  onPurchasePressed(kind) {
    dispatch(sellCheese(kind))
  }

  // More actions...

  render() {
    return(
      <CheeseBox onPurchase={this.onPurchasePressed.bind(this)} />
    )
  }

}

...

export default connect(mapStateToProps)(CheeseApp)
Run Code Online (Sandbox Code Playgroud)

示例组件 - 我们将使用this.props.onPurchase('Cheddar')让容器处理该函数.

// Cheesebox is dumb, keep him that way.
export default class CheeseBox extends Component {

  static propTypes = {
    onPurchase: PropTypes.func.isRequired,
  }

  render() {
    const { onPurchase } = this.props
    return(
      <p>Hi, I love cheese.</p>
      <a onClick={() => onPurchase('Cheddar')} />Buy Now!</a>
    )
  }

}
Run Code Online (Sandbox Code Playgroud)

希望这很有帮助.如果您有任何疑问,请告诉我.


Dro*_*oob 5

一种方法是明智地实现模块化.这样代码将更清晰,更易读.

App
  action/
    component1Actions.js
    ...
    componentnActions.js
    actionTypes.js
  components/
    Component1.js
    ...
    Componentn.js
  container/
    Component1.js
    ...
    Componentn.js
  reducers/
    component1Reducer.js
    ...
    componentnReducer.js
Run Code Online (Sandbox Code Playgroud)

上面显示的结构是我遇到的大多数开发人员使用过的(我更喜欢这种方法).这是有道理的,因为我们根据该文件的性质分隔每个文件.这种方法适用于没有那么多单独文件的中小型项目.

在大型应用程序中,维护代码通常变得困难.

另一种思想流派正在走向领域

app/
  ...
  App.js
  reducers.js
  routes.js
  product/
    Product.js
    ProductContainer.js
    productReducer.js
    ...
  user/
    User.js
    UserContainer.js
    UserActions.js
    userReducer.js
    ...
Run Code Online (Sandbox Code Playgroud)

这样做的好处是我们根据域名分隔文件.例如,应用程序需要用户组件.如果我们将与该域相关的所有文件保存在一个目录下会更容易.这将使app结构在大型应用程序中更清晰.

两者都有好处.在一天结束时,结构无关紧要.这更像是个人选择.


Rob*_*jre 1

我可以考虑两种方法:

  • 在 App.js 的 mapDisatchToProps 中将您的 actionObject 全部组合在一起
  • 您的每个组件都可以成为“容器”组件

示例1:

App.js

import actionObj1 from '../actionComponent1'

export default connect(
  mapStateToProps,
  Object.assign({}, actionObj1, actionObj2, actionObj3)
)(App)
Run Code Online (Sandbox Code Playgroud)

更新(每个子组件成为容器,只需像 App.js 上那样连接):

Component1.js

export default connect(
  mapStateToProps,
  actionObj1)
)(Component1)
Run Code Online (Sandbox Code Playgroud)