javascript - 如何从 React 组件中提取通用逻辑(但通用逻辑是使用 setState)
问题描述
背景
我正在构建一个带有反应的应用程序。我已经使用 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')} />
传递这个感觉是错误的(或者至少有一些破坏性的东西),我想知道这个问题是否有其他解决方案?
解决方案
所以我实际上是在我的另一个项目上做到这一点的。我将其视为在本地设置状态时有一个来自 redux 的 reducer,并且在给定状态并返回整个状态以再次设置时调用一个函数。
这使得跨不同组件的测试和重用变得非常容易。你可以在这里找到这个开源的
我正在做的项目是一个表,所以如果我想转到下一组数据,我会执行以下操作。
(我确实简化了这个例子)
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);
});