如何通过重用代码使用通用方法来定义React组件

时间:2019-01-13 03:48:58

标签: javascript reactjs api single-page-application

我目前有几个React组件,在功能上看起来很相似。它们都有相似的方法,用于通过获取到不同端点的API来获取服务器数据并更新每个组件的状态。

import React, { Component } from 'react';
import { withRouter } from 'react-router-dom';
import AppService from '../lib/service';

class Factorial extends Component {

    constructor(props) {
        super(props);

        this.state = {
            value: '',
        }
    }

    getNext() {
        AppService.getNextFactorial().then(data => {
            this.setState({ value: data.data.gen })
        })
    }

    resetFactorial() {
        AppService.resetNextFactorial().then(data => {
            this.setState({ value: data.data.reset })
        })
    }

    render() {
        return (
            <div className={'functionsWrapper'}>
                <h2> Factorial Sequence Generator </h2>
                <p> Click to get the next value in the sequence </p>
                <button onClick={() => this.getNext()}> Get Next</button>
                <button onClick={() => this.resetFactorial()}> Reset </button>

                <div>
                    <input type="text" id="body" defaultValue={this.state.value} name="body" className="form-input" />
                </div>
            </div>
        )
    }
}

export default withRouter(Factorial);
import React, { Component } from 'react';
import AppService from '../lib/service';

class Fibonacci extends Component {

    constructor(props) {
        super(props);

        this.state = {
            value: '',
        }
    }

    getNext() {
        AppService.getNextFibonacci().then(data => {
            this.setState({ value: data.data.gen })
        })
    }

    resetFibonacci() {
        AppService.resetNextFibonacci().then(data => {
            this.setState({ value: data.data.reset })
        })
    }

    render() {
        return (
            <div className={'functionsWrapper'}>
                <h2> Fibonacci Sequence Generator </h2>
                <p> Click to get the next value in the sequence </p>
                <button onClick={() => this.getNext()}> Get Next</button>
                <button onClick={() => this.resetFibonacci()}> Reset </button>

                <div>
                    <input type="text" id="body" defaultValue={this.state.value} name="body" className="form-input" />
                </div>
            </div>
        )
    }
}

export default Fibonacci;

我想要实现的是能够拆分每个组件的功能并使其可重用,以便我可以采用通用方法

2 个答案:

答案 0 :(得分:2)

helper.js

import AppService from '../lib/service';

export function resetFibonacci() {
    AppService.resetNextFibonacci().then(data => {
        this.setState({ value: data.data.reset })
    });    
}
  

注意:使用带有箭头功能“()=> {}”的功能

Fibonacci.js (您的组件)

import * as Helpers from './helpers.js';
...
resetFibonacci() {
  Helpers.resetFibonacci.call(this);
}
  

注意:将 this 绑定到功能范围。

答案 1 :(得分:1)

您可以创建一个函数来生成组件(组件具有核心功能),然后将差异作为参数传递。

    // componentGenerator.js
    import React, { Component } from 'react';
    import AppService from '../lib/service';

    const componentGenerator = (getNextThing, resetThing, title) => (
    class extends Component {

        constructor(props) {
            super(props);

            this.state = {
                value: '',
            }
        }

        getNext() {
            AppService[getNextThing]().then(data => {
                this.setState({ value: data.data.gen })
            })
        }

        reset() {
            AppService[resetThing]().then(data => {
                this.setState({ value: data.data.reset })
            })
        }

        render() {
            return (
                <div className={'functionsWrapper'}>
                    <h2> {title} </h2>
                    <p> Click to get the next value in the sequence </p>
                    <button onClick={() => this.getNext()}> Get Next</button>
                    <button onClick={() => this.reset()}> Reset </button>

                    <div>
                        <input type="text" id="body" defaultValue={this.state.value} name="body" className="form-input" />
                    </div>
                </div>
            )
        }
    })

    export default componentGenerator;


    // Factorial.js
    import componentGenerator from './componentGenerator';

    export default withRouter(componentGenerator('getNextFactorial', 'resetNextFactorial', 'Factorial Sequence Generator'));


    // Fibonacci.js
    import componentGenerator from './componentGenerator';

    export default withRouter(componentGenerator('getNextFibonacci', 'resetNextFibonacci', 'Fibonacci Sequence Generator'));