gpt4 book ai didi

javascript - 如何将实例变量从 React 组件传递给它的 HOC?

转载 作者:可可西里 更新时间:2023-11-01 02:23:59 25 4
gpt4 key购买 nike

我通常使用组件组合来以 React 方式重用逻辑。例如,这里有一个关于如何向组件添加交互逻辑的简化版本。在这种情况下,我会让 CanvasElement 可选:

CanvasElement.js

import React, { Component } from 'react'
import Selectable from './Selectable'
import './CanvasElement.css'

export default class CanvasElement extends Component {
constructor(props) {
super(props)

this.state = {
selected: false
}

this.interactionElRef = React.createRef()
}

onSelected = (selected) => {
this.setState({ selected})
}

render() {
return (
<Selectable
iElRef={this.interactionElRef}
onSelected={this.onSelected}>

<div ref={this.interactionElRef} className={'canvas-element ' + (this.state.selected ? 'selected' : '')}>
Select me
</div>

</Selectable>
)
}
}

Selectable.js

import { Component } from 'react'
import PropTypes from 'prop-types'

export default class Selectable extends Component {
static propTypes = {
iElRef: PropTypes.shape({
current: PropTypes.instanceOf(Element)
}).isRequired,
onSelected: PropTypes.func.isRequired
}

constructor(props) {
super(props)

this.state = {
selected: false
}
}

onClick = (e) => {
const selected = !this.state.selected
this.setState({ selected })
this.props.onSelected(selected)
}

componentDidMount() {
this.props.iElRef.current.addEventListener('click', this.onClick)
}

componentWillUnmount() {
this.props.iElRef.current.removeEventListener('click', this.onClick)
}

render() {
return this.props.children
}
}

工作得很好。 Selectable 包装器不需要创建新的 div,因为它的父元素为它提供了对另一个将变为可选择的元素的引用。

但是,我曾多次被建议停止使用此类 Wrapper 组合,而是通过 Higher Order Components 实现可重用性。 .愿意尝试 HoC,我尝试了一下,但没有比这更进一步:

CanvasElement.js

import React, { Component } from 'react'
import Selectable from '../enhancers/Selectable'
import flow from 'lodash.flow'
import './CanvasElement.css'

class CanvasElement extends Component {
constructor(props) {
super(props)

this.interactionElRef = React.createRef()
}

render() {
return (
<div ref={this.interactionElRef}>
Select me
</div>
)
}
}

export default flow(
Selectable()
)(CanvasElement)

Selectable.js

import React, { Component } from 'react'

export default function makeSelectable() {
return function decorateComponent(WrappedComponent) {
return class Selectable extends Component {

componentDidMount() {
// attach to interaction element reference here
}

render() {
return (
<WrappedComponent {...this.props} />
)
}
}
}
}

问题是似乎没有明显的方法将增强组件的引用(实例变量)连接到高阶组件(增强器)。

我如何将实例变量(interactionElRef)从 CanvasElement“传递”到它的 HOC?

最佳答案

我想出了一个不同的策略。它的行为大致类似于 Redux connect 函数,提供包装组件不负责创建的 props,但 child 负责在他们认为合适的时候使用它们:

CanvasElement.js

import React, { Component } from "react";
import makeSelectable from "./Selectable";

class CanvasElement extends Component {
constructor(props) {
super(props);
}

render() {
const { onClick, selected } = this.props;
return <div onClick={onClick}>{`Selected: ${selected}`}</div>;
}
}

CanvasElement.propTypes = {
onClick: PropTypes.func,
selected: PropTypes.bool,
};

CanvasElement.defaultProps = {
onClick: () => {},
selected: false,
};

export default makeSelectable()(CanvasElement);

Selectable.js

import React, { Component } from "react";

export default makeSelectable = () => WrappedComponent => {
const selectableFactory = React.createFactory(WrappedComponent);

return class Selectable extends Component {
state = {
isSelected: false
};

handleClick = () => {
this.setState({
isSelected: !this.state.isSelected
});
};

render() {
return selectableFactory({
...this.props,
onClick: this.handleClick,
selected: this.state.isSelected
});
}
}
};

https://codesandbox.io/s/7zwwxw5y41


我知道这不能回答您的问题。我认为您是想让 child 在 parent 不知情的情况下离开。

不过,ref 路由感觉不对。我喜欢将工具与 child 联系起来的想法。您可以在其中任何一个中响应点击。

让我知道你的想法。

关于javascript - 如何将实例变量从 React 组件传递给它的 HOC?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50401485/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com