我来自angular世界,在那里我可以提取逻辑到服务/工厂,并在我的控制器中使用它们。
我试图了解如何在React应用程序中实现相同的功能。
假设我有一个验证用户密码输入的组件(它的强度)。它的逻辑相当复杂,因此我不想把它写在组件中。
我应该把这个逻辑写在哪里?如果我在商店里使用助焊剂?还是有更好的选择?
我来自angular世界,在那里我可以提取逻辑到服务/工厂,并在我的控制器中使用它们。
我试图了解如何在React应用程序中实现相同的功能。
假设我有一个验证用户密码输入的组件(它的强度)。它的逻辑相当复杂,因此我不想把它写在组件中。
我应该把这个逻辑写在哪里?如果我在商店里使用助焊剂?还是有更好的选择?
当前回答
或者你可以将类继承“http”注入到React组件中
通过道具对象。
更新: ReactDOM。render(<ReactApp data={app} />, document.getElementById('root')); 简单地像这样编辑React组件ReactApp: 类ReactApp扩展了React。组件{ 状态= { 数据:“ } 呈现(){ 回报( < div > {this.props.data.getData ()} < / div > ) } }
其他回答
Service并不局限于Angular,甚至在Angular2+中也是如此,
Service只是helper函数的集合…
有很多方法可以创建它们并在应用程序中重用它们……
1)它们可以都是从js文件导出的分离函数,如下所示:
export const firstFunction = () => {
return "firstFunction";
}
export const secondFunction = () => {
return "secondFunction";
}
//etc
2)我们也可以使用工厂方法,比如函数的集合…在ES6中,它可以是一个类而不是函数构造函数:
class myService {
constructor() {
this._data = null;
}
setMyService(data) {
this._data = data;
}
getMyService() {
return this._data;
}
}
在这种情况下,你需要用new key创建一个实例…
const myServiceInstance = new myService();
同样,在这种情况下,每个实例都有自己的生命周期,所以如果你想跨界共享它要小心,在这种情况下,你应该只导出你想要的实例……
3)如果你的函数和utils不会被共享,你甚至可以把它们放在React组件中,在这种情况下,就像函数在React组件中一样…
class Greeting extends React.Component {
getName() {
return "Alireza Dezfoolian";
}
render() {
return <h1>Hello, {this.getName()}</h1>;
}
}
4)另一种你可以处理事情的方法,可以使用Redux,它是你的临时存储,所以如果你在你的React应用程序中有它,它可以帮助你使用许多getter setter函数…它就像一个大的存储,可以跟踪你的状态,并可以在你的组件之间共享它,所以可以摆脱我们在服务中使用的getter setter的许多痛苦……
做一个DRY代码总是好的,不要重复需要使用的东西来让代码可重用和可读,但不要试图在React应用中遵循Angular的方法,就像第4项提到的,使用Redux可以减少你对服务的需求,你可以限制在一些可重用的帮助函数上使用它们,比如第1项……
或者你可以将类继承“http”注入到React组件中
通过道具对象。
更新: ReactDOM。render(<ReactApp data={app} />, document.getElementById('root')); 简单地像这样编辑React组件ReactApp: 类ReactApp扩展了React。组件{ 状态= { 数据:“ } 呈现(){ 回报( < div > {this.props.data.getData ()} < / div > ) } }
可以使用export关键字从包含必要方法的文件中使用函数。
让我举个例子。假设我们有一个名为someservices .ts的文件:
export const foo = (formId: string) => {
// ... the code is omitted for the brevity
}
export const bar = (): Entity[] => [
// ... the code is omitted for the brevity
]
export default {
foo,
bar,
}
然后我们可以像这样在组件中使用这个服务:
import {
foo,
bar,
} from './someService'
const InnerOrderModal: FC = observer(() => {
const handleFormClick = (value: unknown, item: any) => {
foo(item.key)
bar()
return <></>
}
我和你处境相同。在你提到的情况下,我将输入验证UI组件实现为一个React组件。
我同意验证逻辑本身的实现应该(必须)不耦合。因此,我会把它放在一个单独的JS模块中。
也就是说,对于不应该耦合的逻辑,在单独的文件中使用JS模块/类,并使用require/import将组件与“服务”解耦。
这允许独立地进行依赖注入和单元测试。
我也来自Angular,正在尝试React,目前,一个推荐的方法似乎是使用高阶组件:
高阶组件(HOC)是React中的一种高级技术 重用组件逻辑。hoc本身不是React API的一部分。 它们是React的组合特性中出现的一种模式。
假设你有input和textarea,想要应用相同的验证逻辑:
const Input = (props) => (
<input type="text"
style={props.style}
onChange={props.onChange} />
)
const TextArea = (props) => (
<textarea rows="3"
style={props.style}
onChange={props.onChange} >
</textarea>
)
然后编写一个HOC来验证并设置包装组件的样式:
function withValidator(WrappedComponent) {
return class extends React.Component {
constructor(props) {
super(props)
this.validateAndStyle = this.validateAndStyle.bind(this)
this.state = {
style: {}
}
}
validateAndStyle(e) {
const value = e.target.value
const valid = value && value.length > 3 // shared logic here
const style = valid ? {} : { border: '2px solid red' }
console.log(value, valid)
this.setState({
style: style
})
}
render() {
return <WrappedComponent
onChange={this.validateAndStyle}
style={this.state.style}
{...this.props} />
}
}
}
现在这些hoc共享相同的验证行为:
const InputWithValidator = withValidator(Input)
const TextAreaWithValidator = withValidator(TextArea)
render((
<div>
<InputWithValidator />
<TextAreaWithValidator />
</div>
), document.getElementById('root'));
我创建了一个简单的演示。
编辑:另一个演示是使用props来传递一个函数数组,这样你就可以在hoc之间共享由多个验证函数组成的逻辑,比如:
<InputWithValidator validators={[validator1,validator2]} />
<TextAreaWithValidator validators={[validator1,validator2]} />
Edit2: React 16.8+提供了一个新特性Hook,这是另一种共享逻辑的好方法。
const Input = (props) => {
const inputValidation = useInputValidation()
return (
<input type="text"
{...inputValidation} />
)
}
function useInputValidation() {
const [value, setValue] = useState('')
const [style, setStyle] = useState({})
function handleChange(e) {
const value = e.target.value
setValue(value)
const valid = value && value.length > 3 // shared logic here
const style = valid ? {} : { border: '2px solid red' }
console.log(value, valid)
setStyle(style)
}
return {
value,
style,
onChange: handleChange
}
}
https://stackblitz.com/edit/react-shared-validation-logic-using-hook?file=index.js