【问题标题】:How to use HOC and recompose properly如何正确使用 HOC 和重构
【发布时间】:2018-05-03 10:38:10
【问题描述】:

我最近刚开始使用 React,并阅读了 HOC。

我想做类似的事情:使容器可编辑。 我的“解决方案”(因为它还不能正常工作。)

可编辑行(HOC):

import React from 'react'

import { withStateHandlers, withHandlers, compose } from 'recompose'

const editableRow = () =>
    compose(
        withStateHandlers(
            { isEditing: false, editingId: null },
            {
                toggleEditing: ({ isEditing, editingId }) => entryId => ({
                    isEditing: !isEditing,
                    editingId: isEditing ? null : entryId
                })
            }
        ),
        withHandlers({
            handleSave: ({
                isEditing,
                editingId,
                onEdit,
                onCreate,
                list
            }) => values => {
                console.log('handling...')
                if (isEditing) {
                    const entry = list && list.find(entry => entry.id === editingId)
                    return onEdit(entry.id, values) 
                } else return onCreate(values)
            }
        })
    )

export default editableRow

我的数据行:

import React from 'react'
import { Button, Checkbox, Icon, Table, Input } from 'semantic-ui-react'
import PropTypes from 'prop-types'
import editableRow from 'hoc/editableRow'

const DataRow = props => 
    <Table.Row>
        {
            props.children
        }
    </Table.Row>

export default editableRow()(DataRow)

我的组件将接收我使用 HOC 创建的功能和状态, 但由于某种原因,我不能传递任何东西(比如调用回调 [onEdit,onCreate])。并且没有更好的方法来调用 handleSave 而不是 onSubmit={()=>props.handleSave(props1, props2, ...)}

更新:

我的问题是我无法以任何方式向我的组件发送任何“处理程序”。我试过了:

<Table.Row onClick={()=>props.handleSave(
        false,
        false,
        props.onCreate,
        props.onEditing,
        props.list
    )}>
        {
            props.children
        }
    </Table.Row>

但我的 HOC 的 handleSave 只是使用它自己的默认值。我无法联系到他们,所以我无法将任何处理程序传递给它。 我的猜测是我在某处犯了一个非常基本的错误,但不知道在哪里:D

[就像我保存字段时一样。这就是为什么我得到那些 onEditing、onCreating 事件,但即使我将它们传递给我的 HOC 也只是使用它的 OWN DEFAULTs 而不是我传递给它的参数]

请帮助我了解这些是如何工作的......:D

【问题讨论】:

  • 你能告诉你到底是什么问题,因为这个问题很好,但我无法得到你的实际问题
  • 我更新了我的问题。

标签: javascript reactjs callback higher-order-functions higher-order-components


【解决方案1】:
import React from 'react'
import {compose} from 'recompose';
import { Button, Checkbox, Icon, Table, Input } from 'semantic-ui-react'
import PropTypes from 'prop-types'
import editableRow from 'hoc/editableRow'

const DataRow = props => {
    const values = {
        isEditing: false,
        editingId: false,
        onEdit: props.onCreate,
        onCreate: props.onEditing,
        list: props.list,
    };

    return (
        <Table.Row onClick={() => {props.handleSave(values)}}>
            {props.children}
        </Table.Row>
    );
}

export default compose(editableRow)(DataRow);

只要你用HOCcompose你的组件,那么你的HOC就会有你在导出composed组件时提供给这个组件的props

因此,在您的 HOC 中,您可以像这样访问传递的 props

import { withStateHandlers, withHandlers, compose } from 'recompose'

const editableRow = () =>
    compose(
        withStateHandlers(
            { isEditing: false, editingId: null },
            {
                toggleEditing: ({ isEditing, editingId }) => entryId => ({
                    isEditing: !isEditing,
                    editingId: isEditing ? null : entryId
                }),
                handleSave: (state, props) => values => {
                    console.log('handling...')
                    if (isEditing) {
                        const list = values.list;
                        const entry = list && list.find(entry => entry.id === editingId)
                        return props.onEdit(entry.id, values) 
                    } 
                   return props.onCreate(values)
                }
            }
        ),
    )

export default editableRow;

当您使用withStateHandler 时,您不必显式使用withHandlers,它可用于statehandlers。我希望这会有所帮助,如果您仍然卡住,请告诉我。

withStateHandler(arg1: an object or a function to set initial state, {
    callback: (state, props) => callbackValues => {
        //call any callback on props
        props.handleSave(); // or props.onCreate() etc.
        //return desired state from here
    }
})

【讨论】:

  • 哦,这是一个不错的功能。我将有一些时间在一个小时内,将能够测试它。谢谢人:)
  • 如果您认为正确并帮助了您,您应该投票并将其标记为正确答案:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-01-17
  • 2018-07-08
  • 2021-05-22
  • 2021-09-25
  • 2019-01-19
  • 2018-06-05
  • 2017-05-02
相关资源
最近更新 更多