代码之家  ›  专栏  ›  技术社区  ›  Joe Lloyd

如何从react组件中提取公共逻辑(但公共逻辑使用setState)

  •  1
  • Joe Lloyd  · 技术社区  · 6 年前

    我正在用react构建一个应用程序。我已经使用react 2.5年了,但这是我第一次真正开始测试。因此,我从组件中删除了同样多的逻辑。这其中的大部分非常简单,因为对于大多数逻辑来说,用纯函数来思考是很容易的。

    问题

    我发现自己在不同的组件中重用了一个特定的方法,因为它是我的输入字段处理程序。在我第三次复制粘贴之后,我想一定有一个更干净的解决方案。

    此函数当前以完全相同的方式存在于我的3个组件中

    /**
     * @description
     * Returns a function that updates the state form
     *
     * @param {String} stateKey - key in the state to update
     * @returns {Function}
     */
    @autobind
    updateInputValue (prop) {
        return (event) => {
            this.setState({ [prop]: event.target.value });
        }
    };
    

    我试过的

    this 对它来说就像一个变量,它起作用了,但我想知道是否有一个更干净的方法来做它。

    /**
     * @description
     * Returns a function that updates the state of the filter form
     *
     * @param {Object} componentThis - The components context
     * @param {String} stateKey - key in the state to update
     * @returns {Function}
     */
    function updateInputValue (componentThis, stateKey) {
        return (event) => {
            componentThis.setState({ [stateKey]: event.target.value });
        }
    }
    

    然后在输入中

    <Input id="foo"
           value={this.state.foo}
           onChange={updateInputValue(this, 'foo')} />
    

    我想知道这个问题是否还有其他解决方案?

    2 回复  |  直到 6 年前
        1
  •  2
  •   Tall Paul    6 年前

    所以我在另一个项目上做了这个。在本地设置状态时,我将其视为redux的reducer,在给定状态并返回要再次设置的整个状态时,调用一个函数。

    这使得跨不同组件的测试和重用变得非常容易。你可以找到这个 open sourced here

    我正在做的项目是一个表,所以如果我想转到下一组数据,我将执行以下操作。

    import { nextPage } from '../actions/tableActions'
    
    nextPage() {
        this.setState(currentState => {
            return nextPage({ state: currentState })
        });
    };
    

    在我的tableActions.js文件中,它看起来像

    export const nextPage = ({ state }) => {
        const { currentPage } = state.pagination;
    
        return changePage({ ...state, currentPage: currentPage + 1 })
    };
    

    it('should update the currentPage to the next page', () => {
        const given = {
            state: {
                pagination: {
                    currentPage: 2,
                },
            }
        };
        const expected = {
            pagination: {
                currentPage: 3,
            },
        };
    
        expect(actions.nextPage(given)).toEqual(expected);
    });
    
        2
  •  0
  •   Adeel Imran    6 年前

    方法1

    updateInputValue (prop, event) {
       return { [prop]: event.target.value };
    };
    

    在你的代码中

    someFunction = (event) => {
       this.setState(updateInputValue('someFieldkey', event))
    }
    

    方法2

    updateInputValue (theThis, prop, event) {
       theThis.setState({ [prop]: event.target.value });
    };
    

    在你的代码中

    someFunction = (event) => {
       updateInputValue(this, 'someFieldkey', event))
    }
    

    this 在那个函数中引用 setState 方法我认为应该有效。