передать ref в компонент класса с помощью React.cloneElement и отобразить проп - PullRequest
0 голосов
/ 06 мая 2018

Я пишу компонент, который обрабатывает некоторый внутренний state в соответствии с ref его дочернего элемента (например, событие мыши, связанное с ref этого дочернего элемента).
Этот компонент использует render-prop для передачи соответствующего фрагмента state своему дочернему элементу и рендеринга дочернего элемента с ref, прикрепленным через утилиту React.cloneElement.

Проблема в том, что когда дочерний элемент является class компонентом, по какой-то причине ref недоступен, и я не могу найти способ его визуализации, поскольку это объект реагирующего элемента с типом function (после того, как я клонирую это конечно).

Но если дочерний элемент является просто DOM узлом, таким как, например, div, он работает как положено.

Мой обходной путь - проверить тип дочернего элемента, и, если это тип function, я оберну клонированный элемент своим собственным div, если это просто узел dom, то отобразим как есть .
Тем не менее, я бы не хотел оборачивать ребенка дополнительными div, так как я не хочу добавлять ненужные DOM узлы.

Вот базовый пример кода, большая часть кода удалена для краткости:
Родительский компонент:

class Parent extends Component {

    attachRef = node => {
        this.ref = node;
    }

    render() {
        const { render } = this.props;
        const { someValue } = this.state;
        const Child = render(someValue);
        const WithRef = React.cloneElement(Child, {
            ref: this.attachRef
        });
        if (typeof WithRef.type === 'string') { // node element
            return WithRef;
        }
        else if (typeof WithRef.type === 'function') {
            // this is a react element object.. not sure how to render it
            // return ?
        } else {
            // need to find a way to render without a wrapping div
            return (
                <div ref={this.attachRef}>{Child}</div>
            );
        }
    }
}

Использование:

class App extends Component {
    render() {
        return (
            <div>
                <Parent render={someValue => <div> {someValue}</div>} />
                <Parent render={someValue => <Menu someValue={someValue} />} />
            </div>
        );
    }
}

Когда я отрисовываю обычные DOM-узлы, как в первом примере, он работает нормально, когда я пытаюсь отрендерить Menu (который является class компонентом), он не работает, как упомянуто выше.

1 Ответ

0 голосов
/ 28 июня 2018

У меня была почти идентичная проблема.
я решил использовать findDOMNode из react-dom, полное решение можно увидеть в реагировании на внешние нажатия .

Хотя предупреждение отмечает:

findDOMNode - это аварийный штрих, используемый для доступа к базовому узлу DOM. В большинстве случаев использование этого аварийного люка не рекомендуется, потому что пробивает абстракцию компонента.

findDOMNode работает только для смонтированных компонентов (то есть компонентов, которые были помещены в DOM). Если вы попытаетесь вызвать это на компоненте который еще не был подключен (например, вызов findDOMNode () в render () для компонента, который еще не создан) исключение будет выброшены.

findDOMNode нельзя использовать для функциональных компонентов.

Я думаю, что это лучшее решение для этой конкретной задачи.
Это позволит вам быть «прозрачным» для потребителя и одновременно нацелить компонент в DOM.

Хорошо, вот оно, захват ссылки:

componentDidMount() {
    this.ref = findDOMNode(this);
    // some logic ...
}

вот как я использую функцию рендеринга без моей собственной оболочки:

render() {
        const { children, render } = this.props;
        const { clickedOutside } = this.state;
        const renderingFunc = render || children;

        if (typeof renderingFunc === 'function') {
            return renderingFunc(clickedOutside);
        } else {
            return null
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...