【问题标题】:Dispatch handleClick() to redux store调度 handleClick() 到 redux 存储
【发布时间】:2018-02-01 11:22:05
【问题描述】:

我有节点列表,如果我单击其中一个,它应该向 Redux 存储发送一个操作(例如 changeName()),因为我想在另一个组件中使用该节点的属性。

问题在于处理onClick() 事件。如何强制委托?

interface NodeNode {
    id: string;
    Name: string;
    group: number;
}


    export class Nodes extends React.Component<{ nodes: NodeNode[], force: any}, {}>{

    componentDidMount() {
        const simulation = this.props.force;
        d3.selectAll(".node")
            .call(d3.drag()
                .on("start", onDragStart)
                .on("drag", onDrag)
                .on("end", onDragEnd));

    // onDragStart, onDrag, onDragEnd functions
      }

    render(){
        const nodes = this.props.nodes.map((node: NodeNode, index: number) => {
            return <NodeComponent key={index} node={node} onClick={this.handleClick.bind(this)} />;
            });

        return (
            <g className="nodes">
            {nodes}
            </g>
        );
    }

    private handleClick(d: any) {
        alert("clicked!"); // it's clicking but I don't wany to use that method, just dispatch below
    }
}
const mapDispatchToProps = (dispatch: any) => ({
    handleClick: () => dispatch(NodeStore.actionCreators.changeName())
});

export default connect(
    (state: ApplicationState) => state.node,
    mapDispatchToProps
);

我是前端新手。

【问题讨论】:

  • 分派到道具,但在这种情况下,您仍然需要在 React.Component&lt;&gt; 声明中添加 handleClick 函数的定义
  • @Icepickle 但是如果我不想从父级传递它,如何在组件中提供这个handleClick 定义?或者我应该?
  • 由于matchDispatchToProps,它将成为props 的一部分。所以这只是将它添加到extends React.Component&lt;{ handleClick: (d: any) =&gt; void, nodes: NodeNode[], force: any }, {}&gt; 的问题,然后您应该能够通过道具访问它
  • 没什么,你的连接正在处理props的设置
  • 哦,等等,是不是你忘了导出 export default connect((state: ApplicationState) =&gt; state.node, mapDispatchToProps)(Nodes) 了?还是您还在其他地方连接连接?

标签: reactjs typescript redux react-redux


【解决方案1】:

您可以在点击处理程序中调用调度,以防您需要在调用调度之前更改结果

private handleClick(d: any) {
    this.props.handleClick(d);
}

否则将渲染NodeCompenent渲染更改为

... onClick={this.props.handleClick.bind(this)}

我建议使用第一种方法,因为在这种情况下,您可以将绑定移动到构造函数(不要在渲染中使用 .bind());

【讨论】:

  • 因为是typescript,他还是需要在React.Component&lt;&gt;内部提供handleClick调度方法的定义
【解决方案2】:

您可以将handleClick 从类方法更改为属性,之后bind 将是多余的。我也将mapDispatchToProps 符号从函数更改为对象(没有必要=)

interface NodeNode {
    id: string;
    Name: string;
    group: number;
}

export class Nodes extends React.Component<{ nodes: NodeNode[], force: any }, {}> {
    componentDidMount() {
        const simulation = this.props.force;
        d3.selectAll(".node")
            .call(d3.drag()
                .on("start", onDragStart)
                .on("drag", onDrag)
                .on("end", onDragEnd));

        // onDragStart, onDrag, onDragEnd functions
    }

    private handleClick = (d: any) => {
        // Do something and call this.props.handleClick method which you've passed with connect
        this.props.handleClick();
    }

    render() {
        const nodes = this.props.nodes.map((node: NodeNode, index: number) => {
            return <NodeComponent key={ index } node={ node } onClick={ this.handleClick } />;
        });

        return (
            <g className="nodes">
                { nodes }
            </g>
        );
    }
}

const mapDispatchToProps = {
    handleClick: NodeStore.actionCreators.changeName
};

export default connect(
    (state: ApplicationState) => state.node,
    mapDispatchToProps
);

【讨论】:

    【解决方案3】:

    您可以简单地在组件中的任何位置调用 handleClick 调度操作,因为您已将其映射到 mapDispatchToProps。

     this.props.handleClick(); 
    

    代替

     alert("clicked!");
    

    【讨论】:

      猜你喜欢
      • 2017-09-17
      • 1970-01-01
      • 2018-01-06
      • 2021-10-17
      • 2016-06-30
      • 2020-10-12
      • 2019-10-16
      • 2020-09-12
      • 2016-12-14
      相关资源
      最近更新 更多