Как использовать HOC и правильно перекомпоновать - PullRequest
0 голосов
/ 03 мая 2018

Я только недавно начал React и читал о HOC.

Я бы хотел сделать что-то похожее: сделать контейнер редактируемым. Мое «решение» (поскольку оно еще не работает должным образом.)

editableRow (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

My DataRow:

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, ...)}

UPDATE:

Что ж, моя проблема в том, что я никак не могу отправить какой-либо «обработчик» своему компоненту. Я попробовал это как:

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

Но handleSave моего HOC просто использует собственные значения по умолчанию. Я не могу связаться с ними, поэтому я не могу передать какой-либо обработчик к нему. Я предполагаю, что я где-то совершил очень простую ошибку, но не знаю где: D

[Например, когда я сохраняю поле. Вот почему я получил эти события onEditing, onCreating, НО я, даже если я передаю их, мой HOC просто использует свои СОБСТВЕННЫЕ ПО УМОЛЧАНИЮ вместо параметров, которые я передал ему]

ПОМОГИТЕ мне, ребята, пожалуйста, чтобы понять, как они работают ...: D

1 Ответ

0 голосов
/ 03 мая 2018
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);

Всякий раз, когда вы compose добавляете свой компонент к HOC, ваш HOC будет иметь 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;

Вам не нужно явно использовать withHandlers при использовании withStateHandler, который можно использовать как для state, так и для handlers. Надеюсь, это поможет, дайте мне знать, если вы все еще застряли.

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
    }
})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...