Reactjs 如何在Redux中从容器方法分派操作?

Reactjs 如何在Redux中从容器方法分派操作?,reactjs,redux,react-redux,Reactjs,Redux,React Redux,我是Redux的新手,我有一个自己无法解决的问题 我创建了一个待办事项列表应用程序,现在我需要向列表中添加一个新任务。用户在文本输入中写入一些内容,当他单击按钮时,新任务必须附加到列表中 我已获得“添加任务”操作。但我不知道如何从组件方法内部调用它。因此,我在按钮中添加了一个事件侦听器,但当我单击它时,下一步该怎么做 class List extends React.Component{ addTask(e){ var title = $('[name=title]'); t

我是Redux的新手,我有一个自己无法解决的问题

我创建了一个待办事项列表应用程序,现在我需要向列表中添加一个新任务。用户在文本输入中写入一些内容,当他单击按钮时,新任务必须附加到列表中

我已获得“添加任务”操作。但我不知道如何从组件方法内部调用它。因此,我在按钮中添加了一个事件侦听器,但当我单击它时,下一步该怎么做

class List extends React.Component{
  addTask(e){
    var title = $('[name=title]');
    title.val('');
    //what should I do?
  }

  render(){
    const mappedTasks = this.props.tasks.map(function(task){
      return (
        <li key={task.title}>{task.title}</li>
      );
    });

    return (
      <div>
        <ul>
          {mappedTasks}
        </ul>
        <input name='title' />
        <button onClick={this.addTask}>Adicionar</button>
      </div>
    );
  };
}

const mapStateToProps = function(state,ownProps){
  return {
    message: 'Hello World!',
    tasks: state.tasks
  }
}



const ListComponent = connect(
  mapStateToProps
)(List);

我看到了两种可能的解决方案,哪一种更合适可能取决于您的特定用例。有几个问题可能会有所帮助:

  • 这是
    列表
    组件
    连接
    -redux存储区(使用
    react redux
    包中的
    connect()
    装饰器)吗?如果是,您可以 应该能够简单地发送操作,如下所示:
    this.props.dispatch(someActionCreator())
  • 您是否愿意将此组件连接到商店?如果愿意,请将
    列表
    组件装饰为:
    连接(MapStateTops,mapDispatchToProps)(List)
    。然后您可以访问
    列表
    组件中的道具上的
    dispatch()
    ,并可以像问题1一样继续
  • List
    组件是否有一个可以访问
    dispatch()
    函数的祖先。如果有,您可以在该级别创建一个动作调度函数,并将其作为道具向下传递,直到您到达
    List
    组件,在那里您可以调用该函数

  • 正如我所说,您的特定用例将决定每种方法的适用性。如果您还有任何问题,我很乐意提供帮助,请告诉我。

    可以使用类似的方法

    import { Component } from 'react'
    import { bindActionCreators } from 'redux'
    import { connect } from 'react-redux'
    
    import * as TodoActionCreators from './TodoActionCreators'
    console.log(TodoActionCreators)
    // {
    //   addTodo: Function,
    //   removeTodo: Function
    // }
    
    class TodoListContainer extends Component {
      componentDidMount() {
       // Injected by react-redux:
       let { dispatch } = this.props
    
       // Note: this won't work:
       // TodoActionCreators.addTodo('Use Redux')
    
      // You're just calling a function that creates an action.
      // You must dispatch the action, too!
    
      // This will work:
       let action = TodoActionCreators.addTodo('Use Redux')
       dispatch(action)
    }
    
    render() {
    // Injected by react-redux:
       let { todos, dispatch } = this.props
    
    // Here's a good use case for bindActionCreators:
    // You want a child component to be completely unaware of Redux.
    
    let boundActionCreators = bindActionCreators(TodoActionCreators, dispatch)
    console.log(boundActionCreators)
    // {
    //   addTodo: Function,
    //   removeTodo: Function
    // }
    
    return (
      <TodoList todos={todos}
                {...boundActionCreators} />
    )
    
    // An alternative to bindActionCreators is to pass
    // just the dispatch function down, but then your child component
    // needs to import action creators and know about them.
    
    // return <TodoList todos={todos} dispatch={dispatch} />
    }
    }
    
    export default connect(
      state => ({ todos: state.todos })
    )(TodoListContainer)
    
    从'react'导入{Component}
    从“redux”导入{bindActionCreators}
    从“react redux”导入{connect}
    从“./TodoActionCreators”导入*作为TodoActionCreators
    console.log(TodoActionCreators)
    // {
    //addTodo:函数,
    //removeTodo:函数
    // }
    类TodoListContainer扩展组件{
    componentDidMount(){
    //由react redux注入:
    让{dispatch}=this.props
    //注意:这不起作用:
    //TodoActionCreators.addTodo('Use Redux')
    //您只是调用一个创建操作的函数。
    //你也必须采取行动!
    //这将有助于:
    let action=TodoActionCreators.addTodo('Use Redux'))
    派遣(行动)
    }
    render(){
    //由react redux注入:
    让{todos,dispatch}=this.props
    //下面是bindActionCreators的一个很好的用例:
    //您希望子组件完全不知道Redux。
    让boundActionCreators=bindActionCreators(TodoActionCreators,调度)
    console.log(boundActionCreators)
    // {
    //addTodo:函数,
    //removeTodo:函数
    // }
    返回(
    )
    //bindActionCreators的另一种选择是通过
    //只需关闭分派函数,然后关闭子组件
    //需要导入动作创建者并了解他们。
    //返回
    }
    }
    导出默认连接(
    state=>({todos:state.todos})
    )(TodoListContainer)
    
    在组件中分派操作的一种最常见的方法是使用mapDispatchToProps将操作分发给props。然后您可以从props分派操作

    componentWillMount() {   
       this.props.actions.loadPropImages();
    }
    
    function mapDispatchToProps(dispatch) {
      return {
        actions: bindActionCreators(imageActions, dispatch) 
      };
    }
    
    export default connect(mapStateToProps, mapDispatchToProps)(EditorPage);
    

    我用我的
    connect
    函数更新了我的问题。
    组件方法中的此
    为空。
    MapStateTrops
    工作正常,正在重新渲染
    import { Component } from 'react'
    import { bindActionCreators } from 'redux'
    import { connect } from 'react-redux'
    
    import * as TodoActionCreators from './TodoActionCreators'
    console.log(TodoActionCreators)
    // {
    //   addTodo: Function,
    //   removeTodo: Function
    // }
    
    class TodoListContainer extends Component {
      componentDidMount() {
       // Injected by react-redux:
       let { dispatch } = this.props
    
       // Note: this won't work:
       // TodoActionCreators.addTodo('Use Redux')
    
      // You're just calling a function that creates an action.
      // You must dispatch the action, too!
    
      // This will work:
       let action = TodoActionCreators.addTodo('Use Redux')
       dispatch(action)
    }
    
    render() {
    // Injected by react-redux:
       let { todos, dispatch } = this.props
    
    // Here's a good use case for bindActionCreators:
    // You want a child component to be completely unaware of Redux.
    
    let boundActionCreators = bindActionCreators(TodoActionCreators, dispatch)
    console.log(boundActionCreators)
    // {
    //   addTodo: Function,
    //   removeTodo: Function
    // }
    
    return (
      <TodoList todos={todos}
                {...boundActionCreators} />
    )
    
    // An alternative to bindActionCreators is to pass
    // just the dispatch function down, but then your child component
    // needs to import action creators and know about them.
    
    // return <TodoList todos={todos} dispatch={dispatch} />
    }
    }
    
    export default connect(
      state => ({ todos: state.todos })
    )(TodoListContainer)
    
    componentWillMount() {   
       this.props.actions.loadPropImages();
    }
    
    function mapDispatchToProps(dispatch) {
      return {
        actions: bindActionCreators(imageActions, dispatch) 
      };
    }
    
    export default connect(mapStateToProps, mapDispatchToProps)(EditorPage);