为(点击处理程序)函数创建辅助函数以在多个 React 组件中重用
Create helper function for a (click handler) function to reuse in multiple React components
对于 'back' 我在我的 React 应用中创建的按钮 (onClick) 处理函数。
const { length: historyLength, goBack, replace } = useHistory();
const handleBack = () => {
if (historyLength > 2) {
goBack();
} else {
// History length is 2 by default when nothing is pushed to history yet
//
replace(HomePage);
}
};
然后我将 onClick 处理程序传递给我的子组件,例如:<Button onClick={handleBack}/>
我在我的 React 应用程序的多个地方使用这个 handleBack
函数。这是一个好的方法吗?一个辅助函数,具体如何?
@meez
不明白为什么这行不通。只有几件事:(a)我会在函数中添加事件参数和 e.preventDefault()
并且(b)会小心你传递给 onClick
属性 的函数名称你的按钮:handleBackClick !== handleBack
,你会得到一个 ReferenceError 因为一个未定义的函数。
此外,我还注意到,这可以通过浏览器的原生功能来实现。这是一个片段:
const { length: historyLength, back } = window.history;
const { replace } = window.location;
const handleBack = (e) => {
e.preventDefault();
if (historyLength > 2) {
back();
} else {
replace('homepageUrl');
}
};
我也没有发现代码或将其用作实用程序回调有任何问题。
Is it a good approach make it e.g. a helper function and how exactly?
任何时候你都可以让你的代码更DRY(不要重复自己)这通常是一件好事。我个人的 rule-of-thumb 是,如果我第三次编写相同的实用程序代码,我会花一点时间将其重构为通用实用程序(和单元测试!!).
我可能会建议为 return 后处理程序创建一个自定义挂钩。
示例:
import { useHistory } from 'react-router-dom';
const useBackHandler = () => {
const history = useHistory();
const handleBack = React.useCallback(() => {
const { length: historyLength, goBack, replace } = history;
if (historyLength > 2) {
goBack();
} else {
replace(HomePage);
}
}, []);
return handleBack;
};
export default useBackHandler;
现在您可以导入和使用一个挂钩。
import useBackHandler from '../path/to/useBackHandler';
...
const backHandler = useBackHandler();
...
<button type="button" onClick={backHandler}>Back?</button>
如果您需要在较旧的 class 组件中使用此功能,那么您将需要一种方法将 handleBack
作为道具注入。为此,您可以创建一个高阶组件。
示例:
import useBackHandler from '../path/to/useBackHandler';
const withBackHandler = Component => props => {
const backHandler = useBackHandler();
return <Component {...props} backHandler={backHandler} />;
};
export default withBackHandler;
要使用,导入 withBackHandler
并装饰一个 React 组件并访问 props.backHandler
。
import withBackHandler from '../path/to/withBackHandler';
class MyComponent extends React.Component {
...
someFunction = () => {
...
this.props.backHandler();
}
...
}
export default withBackHandler(MyComponent);
对于 'back' 我在我的 React 应用中创建的按钮 (onClick) 处理函数。
const { length: historyLength, goBack, replace } = useHistory();
const handleBack = () => {
if (historyLength > 2) {
goBack();
} else {
// History length is 2 by default when nothing is pushed to history yet
//
replace(HomePage);
}
};
然后我将 onClick 处理程序传递给我的子组件,例如:<Button onClick={handleBack}/>
我在我的 React 应用程序的多个地方使用这个 handleBack
函数。这是一个好的方法吗?一个辅助函数,具体如何?
@meez
不明白为什么这行不通。只有几件事:(a)我会在函数中添加事件参数和 e.preventDefault()
并且(b)会小心你传递给 onClick
属性 的函数名称你的按钮:handleBackClick !== handleBack
,你会得到一个 ReferenceError 因为一个未定义的函数。
此外,我还注意到,这可以通过浏览器的原生功能来实现。这是一个片段:
const { length: historyLength, back } = window.history;
const { replace } = window.location;
const handleBack = (e) => {
e.preventDefault();
if (historyLength > 2) {
back();
} else {
replace('homepageUrl');
}
};
我也没有发现代码或将其用作实用程序回调有任何问题。
Is it a good approach make it e.g. a helper function and how exactly?
任何时候你都可以让你的代码更DRY(不要重复自己)这通常是一件好事。我个人的 rule-of-thumb 是,如果我第三次编写相同的实用程序代码,我会花一点时间将其重构为通用实用程序(和单元测试!!).
我可能会建议为 return 后处理程序创建一个自定义挂钩。
示例:
import { useHistory } from 'react-router-dom';
const useBackHandler = () => {
const history = useHistory();
const handleBack = React.useCallback(() => {
const { length: historyLength, goBack, replace } = history;
if (historyLength > 2) {
goBack();
} else {
replace(HomePage);
}
}, []);
return handleBack;
};
export default useBackHandler;
现在您可以导入和使用一个挂钩。
import useBackHandler from '../path/to/useBackHandler';
...
const backHandler = useBackHandler();
...
<button type="button" onClick={backHandler}>Back?</button>
如果您需要在较旧的 class 组件中使用此功能,那么您将需要一种方法将 handleBack
作为道具注入。为此,您可以创建一个高阶组件。
示例:
import useBackHandler from '../path/to/useBackHandler';
const withBackHandler = Component => props => {
const backHandler = useBackHandler();
return <Component {...props} backHandler={backHandler} />;
};
export default withBackHandler;
要使用,导入 withBackHandler
并装饰一个 React 组件并访问 props.backHandler
。
import withBackHandler from '../path/to/withBackHandler';
class MyComponent extends React.Component {
...
someFunction = () => {
...
this.props.backHandler();
}
...
}
export default withBackHandler(MyComponent);