[英]Reuse component logic in React
I have a more general/conceptual question - in React, how does one go about creating a component that can be build upon.我有一个更一般/概念性的问题 - 在 React 中,一个 go 如何创建一个可以构建的组件。 Let me explain:
让我解释:
Say we have a <PersonalInfo.jsx/>
and in it we have text fields for name
, age
and address
.假设我们有一个
<PersonalInfo.jsx/>
,其中我们有name
、 age
和address
的文本字段。 The application can be used both by civilians and by police officers.该应用程序可供平民和警察使用。 If it is used by a police officer we also want to have a field
department number
between age
and address
.如果它被警察使用,我们还希望在
age
和address
之间有一个现场department number
。 It can also be used by doctors and in that case we need to add a specialization
field between name
and age
.医生也可以使用它,在这种情况下,我们需要在
name
和age
之间添加一个specialization
字段。 One way is to have a <PoliceOfficerPersonalInfo.jsx/>
and just duplicate everything (ugh.).一种方法是拥有一个
<PoliceOfficerPersonalInfo.jsx/>
并复制所有内容(呃。)。 Another way is to use a HOC but I can't figure out how to go about it exactly?另一种方法是使用 HOC,但我不知道如何准确了解 go? Any other ideas?
还有其他想法吗?
I don't see how a Higher Order Component would/could help solve this issue as a HOC is really only is capable of injecting props and behavior, but they can't go and change the UI, ie the JSX.我看不出高阶组件如何/可以帮助解决这个问题,因为 HOC 实际上只能注入道具和行为,但它们不能 go 并更改 UI,即 JSX。
React is designed with composition in mind, so you should think abstractly about the UI elements that make up what a "PersonalInfo" component is, ie what are the smaller building block components that can be created to compose a larger component. React 在设计时考虑了组合,因此您应该抽象地考虑构成“PersonalInfo”组件的 UI 元素,即可以创建哪些较小的构建块组件来组合较大的组件。 From what you've provided I'm guessing you have a collection of fields/properties that when taken together represent a person's "personal info".
根据您提供的内容,我猜您有一组字段/属性,这些字段/属性放在一起代表一个人的“个人信息”。
From here you go one of few directions:从这里你 go 几个方向之一:
PersonalInfo
and PoliceOfficerPersonalInfo
components.PersonalInfo
和PoliceOfficerPersonalInfo
组件。 Pro is each component has a single specific use, but the con is if any field that is common to multiple components needs to be updated you may need to track them all down (mitigated if compositional building blocks designed well).children
prop.children
属性呈现子级。 The pro here is you get the container you want to put the UI in, and you decide at design time what children to display.<PersonalInfo>{props.children}</PersonalInfo>
.<PersonalInfo>{props.children}</PersonalInfo>
。 A con could be that you don't have a pre-fabricated specialized component lying around to just slap in somewhere.There are many approaches that you can use but I would just create component as CommonTextFields and use for repeated part.您可以使用许多方法,但我只会将组件创建为 CommonTextFields 并用于重复部分。 It is more readable and maintable that way even though you have some level of code repeat.
即使您有一定程度的代码重复,它也更具可读性和可维护性。
const PageA = () => {
// do your validation and fetch logic here
return (
<>
<CommonFields age={age} name={name} value={address} />
<FieldA value={fieldA} />
</>
);
};
const PageB = () => {
// do your validation and fetch logic here
return (
<>
<CommonFields />
<FieldB />
</>
);
};
But if you insist non render parts (validation / fetch logic etc..) to not repeat too (which is i think bad idea as it will kill maintability).但是,如果您坚持非渲染部分(验证/获取逻辑等)也不要重复(我认为这是个坏主意,因为它会破坏可维护性)。 There are HOC and renderProps options;
有 HOC 和 renderProps 选项; also you may support this with customHooks.
您也可以使用 customHooks 来支持这一点。 But in that case you need to find a way to include to the fetch and validation logic for the parts that are not repeated.
但是在这种情况下,您需要找到一种方法来包含不重复部分的获取和验证逻辑。
// Really looks so messy and not scalable
// Yhis is only one field, imagine for array of fields
const CommonFieldsHOC => ( Field, fieldName, validationFunc ) => ( props ) => {
const [extraField, setExtraField] = useState()
const commonValidation = () => {}
// Find a way to include extraFields logic to validation and Fetch
handleSubmit = () => {
const isCommonFieldsValid = commonValidation()
const isFieldValid = validationFunc(extraField)
if(isFieldValid && isCommonFieldsValid) {
submitFunction({ name, age, address,
[fieldName]: extraField
})
} else {
// give some warning
}
}
return (
<>
<Name value={name} />
<Age value={age} />
<Address value={address} />
<Field value={extraField} onChange={extraField} />
<Button onClick={handleSubmit}>
</>
)
};
And use it like this:并像这样使用它:
const MyExtraField = () => <MyExtraField />
const validateMyExtraField = (value) => value > 0
const MyForm = CommonFieldsHOC(MyExtraField, 'MyExtraField', validateMyExtraField )
const Page = () => {
return <>
<MyForm />
</>
}
you can add a Boolean to show or hide a specific information in the component so you can reuse it.您可以添加Boolean以显示或隐藏组件中的特定信息,以便您可以重复使用它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.