如何在 React-Recompose 应用程序中将事件处理程序传递给 React-node

Posted

技术标签:

【中文标题】如何在 React-Recompose 应用程序中将事件处理程序传递给 React-node【英文标题】:How to pass event handlers to React-node in React-Recompose App 【发布时间】:2019-03-26 22:26:36 【问题描述】:

在:https://github.com/BeerDRinker/recompose-ref 获得工作应用程序

以下代码(/src/App.js 中的注释部分)按预期工作:

class App extends Component 
constructor(props) 
    super(props);

    this.node = React.createRef();
    this.state = 
        value: 1
    ;


handleTouchStart = e => 
    e.preventDefault();
    this.setState( value: this.state.value + 1 );
;

handleTouchEnd = e => 
    e.preventDefault();
    this.setState( value: this.state.value - 1 );
;

componentDidMount() 
    this.node.current.ontouchstart = this.handleTouchStart;
    this.node.current.ontouchend = this.handleTouchEnd;


render() 
    return (
        <div>
            <h3>Value: this.state.value</h3>
            <button ref=this.node>Submit</button>
        </div>
    );
    


export default App;

但我需要使用 Recompose 来获得相同的功能。我试过了,但没有任何效果。我的代码示例(在 /src/App.js 中未注释部分)不起作用:

import React from "react";
    import 
        compose,
        lifecycle,
        setDisplayName,
        withProps,
       withStateHandlers
 from "recompose";

import "./App.css";

const state = 
    value: 1
;

const stateHandlers = 
    handleTouchStart: value => () => (
        value: value + 1
    ),
    handleTouchEnd: value => () => (
        value: value - 1
    )
;

export const enhance = compose(
    setDisplayName("App"),
    withProps(props => (
        bookNode: React.createRef()
    )),
    withStateHandlers(state, stateHandlers),
    lifecycle(
        componentDidMount() 
            this.bookNode.current.ontouchstart =   
            this.handleTouchStart;
            this.bookNode.current.ontouchend = this.handleTouchEnd;
        
    )
);

export const App = ( value, bookNode ) => (
    <div>
        <h3>Value: value</h3>
        <button ref=bookNode>Submit</button>
    </div>
);

export default enhance(App);

刚开始使用 recompose,很多东西对我来说仍然很神奇)) 我希望有人能帮助我,通过几天来解决这个问题。

【问题讨论】:

【参考方案1】:

组合组件有问题。

this 上没有 bookNode 和事件处理程序。 App 是无状态组件,无法访问 thisbookNode 和事件处理程序是道具。

顾名思义,传递给 state 处理程序的不是 value,而是 state

应该是:

const stateHandlers = 
    handleTouchStart: state => () => (
        value: state.value + 1
    ),
    handleTouchEnd: state => () => (
        value: state.value - 1
    )
;

export const enhance = compose(
    setDisplayName("App"),
    withProps(props => (
        bookNode: React.createRef()
    )),
    withStateHandlers(state, stateHandlers),
    lifecycle(
        componentDidMount() 
            this.props.bookNode.current.ontouchstart = this.props.handleTouchStart;
            this.props.bookNode.current.ontouchend = this.props.handleTouchEnd;
        
    )
);

export const App = ( value, bookNode ) => (
    <div>
        <h3>Value: value</h3>
        <button ref=bookNode>Submit</button>
    </div>
);

这是demo。

通常没有理由手动访问 DOM 来设置事件,因为 React 会处理这个问题。这消除了对 ref 和生命周期钩子的需要:

export const enhance = compose(
    setDisplayName("App"),
    withStateHandlers(state, stateHandlers)
);

const App = ( value, handleTouchStart, handleTouchEnd ) => (
    <div>
        <h3>Value: value</h3>
        <button onTouchStart=handleTouchStart onTouchEnd=handleTouchEnd>Submit</button>
    </div>
);

【讨论】:

在我的情况下,我需要阻止默认的 onTouchStart。但是在 Google Chrome 中,他们在 56 及更高版本中删除了 .preventDefoult() 方法。更多信息在这里:github.com/facebook/react/issues/9809#issuecomment-413978405developers.google.com/web/updates/2017/01/…

以上是关于如何在 React-Recompose 应用程序中将事件处理程序传递给 React-node的主要内容,如果未能解决你的问题,请参考以下文章

如何在应用程序中调整亮度[重复]

如何在 Cocoa 应用程序中显示文件列表?

如何在电子应用程序标题中添加空格?

如何在颤振应用程序中无上下文导航?

如何在我的应用程序中接收共享内容?

如何在 Iphone 应用程序中隐藏状态栏