javascript - 创建一个封装耦合 React 组件的类,然后将该类设置为 React 状态?

标签 javascript reactjs web react-router react-redux

我有一个 React 组件,它呈现一个 FullDayRouteMap 组件,该组件接受状态累加器以及几个 SingleRouteMap 组件,每个组件都会执行更新状态累加器的回调。

然后,FullDayRouteMap 组件将这些更新的累加器作为 props 并重新渲染。

我想将两个组件(即累加器和回调)的耦合功能封装在一个类中,以便我可以在应用程序的多个部分中重用此功能,因此我创建了一个设置为状态的 Manager 类其构造函数中的父 React 组件。

一切正常,但我想知道这是否是一个好的做法。我有点不确定的是,我必须将父组件传递给这个管理器类,以便强制它在累加器更新时重新渲染

这是该管理器类的代码(为了简洁而缩短):

import React from 'react';
import SingleRouteMap from './SingleRouteMap';
import FullDayRouteMap from './FullDayRouteMap';

class Manager {

    constructor(component) {
        this.distanceMetresAcc = 0;
        this.travelTimeSecondsAcc = 0;
    }


    initSingleRouteMap(bookingNodes) {
        bookingNodes.push(
            <SingleRouteMap
                onDirectionsDataLoaded={this.onSingleRouteLoaded} />);
    }

    getFullDayRouteMap() {
        return <FullDayRouteMap
            totalDistanceTravelledMetres={this.distanceMetresAcc}
            totalSecondsTravelled={this.travelTimeSecondsAcc}
        />
    }

    onSingleRouteLoaded = (durationSeconds, distanceMetres) => {
        this.travelTimeSecondsAcc += durationSeconds;
        this.distanceMetresAcc += distanceMetres;
        this.component.forceUpdate();
    };
}

在我的父组件中,这就是我所做的:

Parent extends Component {
    constructor(props) {
        super(props);

        this.state = {
            manager: new Manager(this)
        }
    }
}

然后,渲染函数只需调用 this.state.manager.initSingleRouteMapthis.state.manager.getFullDayRouteMap 即可将这些组件动态放置在 UI 中。

最佳答案

使用 HOC 解决问题

function withRouteAcc(WrappedComponent) {
    return class extends Component {
        constructor(props) {
            super(props);
            this.state = {
                distanceMetresAcc: 0,
                travelTimeSecondsAcc: 0,
                bookingNodeCount: 0
            };
        }

        initSingleRouteMap() {
            this.setState(
                (state) => (
                    { bookingNodeCount: state.bookingNodeCount + 1 }
                )
            );
        }

        onSingleRouteLoaded(durationSeconds, distanceMetres) {
            this.setState((state) => (
                    {
                        distanceMetresAcc: state.distanceMetresAcc + distanceMetres,
                        travelTimeSecondsAcc: state.travelTimeSecondsAcc +
                                              durationSeconds
                    }
                )
            );
        }

        getBookingNodes() {
            return this.state.bookingNodeCount.map(() => {
                return <SingleRouteMap onDirectionsDataLoaded={this.onSingleRouteLoaded}/>;
            });
        }

        getFullDayRouteMap() {
            return <FullDayRouteMap totalDistanceTravelledMetres={this.distanceMetresAcc}
                                    totalSecondsTravelled={this.travelTimeSecondsAcc}/>;
        }

        render() {
            <WrappedComponent {...this.props} 
                              bookingNodes={this.getBookingNodes()}
                              fullDayRouteMap={this.getFullDayRouteMap()}
                              initSingleRouteMap={this.initSingleRouteMap}/>;
        }
    };
}

//Usage: withRouteAcc(ParentComponent);
// Now `ParentComponent` can access `bookingNodes` and `fullDayRouteMap` from props, as well as a callback for `initSingleRouteMap`

关于javascript - 创建一个封装耦合 React 组件的类,然后将该类设置为 React 状态?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48429379/

相关文章:

javascript - 在没有 combineLatest 的情况下从另一个可观察对象获取值(value)的最佳方法

javascript - 如何获取在 Canvas 上移动的图像的 X 和 Y 坐标

javascript - 如何从 JavaScript 刷新 PrimeFaces Editor 组件

javascript - 如何从单个构建加载单独的组件

javascript - 使用 Link React 传递参数

php - 所有表单字段都工作正常,但图像未插入表中,其为空并且不显示任何错误,如下所示

html - 响应式网页设计中的表格

javascript - 当我调用它时,angular 的 $rootScope.$on() 方法没有被触发。为什么?

javascript - 我怎样才能只允许 React 组件的单个实例存在?

javascript - 导出到 ui-grid 中的 csv : exporterAllDataFn fires only when we have more than one page