如果满足特定条件,有没有办法只向 React 组件添加属性?
我应该在渲染后基于 Ajax 调用向表单元素添加 required 和 readOnly 属性,但我看不出如何解决这个问题,因为 readOnly="false"
与完全省略该属性不同。
下面的示例应该解释我想要什么,但它不起作用。
(解析错误:意外的标识符)
function MyInput({isRequired}) {
return <input classname="foo" {isRequired ? "required" : ""} />
}
aria-modal=true
,您将更改(为 false)推送到 aria/data 属性的存储区,但没有其他任何更改(例如组件的内容或类或变量) ) 结果 ReactJs 不会更新该组件中的 aria/data attrs。我一直在胡闹一整天才意识到这一点。
显然,对于某些属性,如果您传递给它的值不真实,React 足够智能,可以忽略该属性。例如:
const InputComponent = function() {
const required = true;
const disabled = false;
return (
<input type="text" disabled={disabled} required={required} />
);
}
将导致:
<input type="text" required>
更新:如果有人对这种情况发生的方式/原因感到好奇,您可以在 ReactDOM 的源代码中找到详细信息,特别是在 DOMProperty.js 文件的第 30 和 167 行。
juandemarco's answer 通常是正确的,但这里有另一个选项。
以您喜欢的方式构建对象:
var inputProps = {
value: 'foo',
onChange: this.handleChange
};
if (condition) {
inputProps.disabled = true;
}
使用传播进行渲染,也可以选择传递其他道具。
<input
value="this is overridden by inputProps"
{...inputProps}
onChange={overridesInputProps}
/>
_extends
已添加到其中,这将(在正常情况下)占用props
从“正常属性”构造并应用 Object.assign(props, inputProps)
。
以下是通过 React-Bootstrap(版本 0.32.4)使用 Bootstrap 的 Button
的示例:
var condition = true;
return (
<Button {...(condition ? {bsStyle: 'success'} : {})} />
);
根据条件,将返回 {bsStyle: 'success'}
或 {}
。然后,展开运算符会将返回对象的属性展开到 Button
组件。在虚假情况下,由于返回的对象上不存在任何属性,因此不会将任何内容传递给组件。
基于 Andy Polhill's comment 的另一种方法:
var condition = true;
return (
<Button bsStyle={condition ? 'success' : undefined} />
);
唯一的小区别是,在第二个示例中,内部组件 <Button/>
的 props
对象将具有一个值为 undefined
的键 bsStyle
。
{bsStyle: 'success'}
或 {}
结果),然后扩展该对象。
<Button bsStyle={ condition ? 'success': undefined } />
我发现语法稍微容易一些,传递 undefined
将省略该属性。
<Button/>
的 props
对象将有一个值为 undefined
的键 bsStyle
。
onChange
的情况下不对设置的 checked
值发出警告的解决方案(即使 checked
被设置为 false)。所以{...(checked ? {checked} : {})}
。感谢您的解决方案!
style={{...(isReadOnly ? styles.readOnly : {}), ...styles.baseStyle }}
然后,在组件内部,您可以将它混合到组件使用的任何样式中:<Text style={...props.style, ...localStyleClass} >Hello World<Text>
这是一个替代方案。
var condition = true;
var props = {
value: 'foo',
...(condition && { disabled: true })
};
var component = <div {...props} />;
或其内联版本
var condition = true;
var component = (
<div value="foo" {...(condition && { disabled: true })} />
);
condition
为 false,这将尝试扩展/迭代 false,我认为这是不正确的。
false
不是一个。只需与 Babel 核对即可。当 condition
评估为 false 时,这适用于它,因为 Babel 实现运算符的方式。虽然一个简单的解决方法可能是 ...( condition ? { disabled: true } : {} )
,但它变得有点冗长。感谢您的精彩输入!
data-*
或 aria-*
属性,则需要此方法,因为它们是 JSX 中的特殊情况,因此 data-my-conditional-attr={ false }
将输出 data-my-conditional-attr="false"
而不是省略属性。 facebook.github.io/react/docs/dom-elements.html
这是我这样做的一种方式。
有条件:
<Label
{...{
text: label,
type,
...(tooltip && { tooltip }),
isRequired: required
}}
/>
我仍然更喜欢使用常规方式传递道具,因为在没有任何条件的情况下(在我看来)它更具可读性。
无条件:
<Label text={label} type={type} tooltip={tooltip} isRequired={required} />
...(tooltip && { tooltip }),
?它确实适用于组件,但是当我尝试在代码中使用类似这样的东西时,我收到一个错误,这意味着我尝试传播不可迭代的值
falseyValue && {}
将返回 false,因此您很可能在传播 false,例如 ...(false)
。使用完整表达式要好得多,因此传播继续表现...(condition ? {foo: 'bar'} : {})
假设如果条件为真,我们想要添加自定义属性(使用 aria-* 或 data-*):
{...this.props.isTrue && {'aria-name' : 'something here'}}
假设如果条件为真,我们要添加样式属性:
{...this.props.isTrue && {style : {color: 'red'}}}
您可以使用相同的快捷方式,用于添加/删除(部分)组件 ({isVisible && <SomeComponent />}
)。
class MyComponent extends React.Component {
render() {
return (
<div someAttribute={someCondition && someValue} />
);
}
}
someCondition
为真但 someValue
为假(例如 false
本身或 0
等),是否仍包含该属性?如果需要显式包含一个虚假值,例如坐标属性的 0
等,这一点很重要。
data-*
和 aria-*
的情况下不会,请参阅我上面的评论。如果您引用该值,或将其转换为字符串,则该属性将显示:例如 someAttr={ `${falsyValue}` }
可以呈现 someAttr="false"
如果你使用 ECMAScript 6,你可以简单地这样写。
// First, create a wrap object.
const wrap = {
[variableName]: true
}
// Then, use it
<SomeComponent {...{wrap}} />
这应该可行,因为您的状态将在 Ajax 调用后发生变化,并且父组件将重新呈现。
render : function () {
var item;
if (this.state.isRequired) {
item = <MyOwnInput attribute={'whatever'} />
} else {
item = <MyOwnInput />
}
return (
<div>
{item}
</div>
);
}
使用 undefined
适用于大多数属性:
const name = "someName";
return (
<input name={name ? name : undefined} />
);
例如使用自定义容器的属性样式
const DriverSelector = props => {
const Container = props.container;
const otherProps = {
...( props.containerStyles && { style: props.containerStyles } )
};
return (
<Container {...otherProps} >
对于 React [1] 列出的一些布尔属性:
<input disabled={disabled} />
// renders either `<input>` or `<input disabled>`
对于其他属性:
<div aria-selected= {selected ? "" : undefined} />
// renders either `<div aria-selected></div>` or `<div></div>`
在 React 中,你可以有条件地渲染组件,也可以渲染它们的属性,比如 props、className、id 等等。
在 React 中,使用 ternary operator 是一种很好的做法,它可以帮助您有条件地渲染组件。
一个示例还展示了如何有条件地渲染 Component 及其样式属性。
这是一个简单的例子:
类 App 扩展 React.Component { state = { isTrue: true }; render() { return (
从我的角度来看,管理多个条件 props 的最佳方法是 @brigand 的 props object 方法。但可以改进它以避免为每个条件道具添加一个 if
块。
ifVal 助手
随意重命名(iv,condVal,cv,_,...)
如果满足条件,您可以定义一个辅助函数来返回一个值或另一个值:
// components-helpers.js
export const ifVal = (cond, trueValue=true, falseValue=null) => {
return cond ? trueValue : falseValue
}
如果 cond
是 true
(或 truthy),则返回 trueValue
- 或 true
。如果 cond
为 false
(或 falsy),则返回 falseValue
- 或 null
。
这些默认值(true
和 null
)通常是允许将 prop 传递或不传递给 React 组件的正确值。您可以将此函数视为“改进的 React 三元运算符”。如果您需要对返回值进行更多控制,请对其进行改进。
让我们将它与许多道具一起使用。
构建(复杂的)道具对象
// your-code.js
import { ifVal } from './components-helpers.js'
// BE SURE to replace all true/false with a real condition in you code
// this is just an example
const inputProps = {
value: 'foo',
enabled: ifVal(true), // true
noProp: ifVal(false), // null - ignored by React
aProp: ifVal(true, 'my value'), // 'my value'
bProp: ifVal(false, 'the true text', 'the false text') // 'my false value',
onAction: ifVal(isGuest, handleGuest, handleUser) // it depends on isGuest value
};
<MyComponent {...inputProps} />
这种方法类似于使用 classnames utility 有条件地管理类的流行方法,但适用于 props。
为什么你应该使用这种方法
即使有许多条件 props,您也将拥有清晰易读的语法:每个新 prop 只需在对象声明中添加一行代码。
通过这种方式,您可以替换重复运算符(...
、&&
、? :
、...)的语法噪音,当您有许多道具时,这可能会非常烦人,函数调用。
作为开发人员,我们的首要任务是编写最明显的代码来解决问题。太多次我们为自我解决问题,在不需要的地方增加了复杂性。对于今天的我们、明天的我们和我们的伙伴,我们的代码应该简单明了。
仅仅因为我们可以做某事并不意味着我们应该
我希望这个迟到的回复会有所帮助。
<input checked={true} type="checkbox" />
在反应功能组件中,您可以尝试这样的事情来省略不必要的标签属性。
<div className="something" ref={someCondition ? dummyRef : null} />
如果我需要省略 ref、class 等标签,这对我有用。但我不知道这是否适用于每个标签属性
考虑到帖子 JSX In Depth,您可以通过以下方式解决您的问题:
if (isRequired) {
return (
<MyOwnInput name="test" required='required' />
);
}
return (
<MyOwnInput name="test" />
);
我认为这可能对那些希望属性值成为函数的人有用:
import { RNCamera } from 'react-native-camera';
[...]
export default class MyView extends React.Component {
_myFunction = (myObject) => {
console.log(myObject.type); //
}
render() {
var scannerProps = Platform.OS === 'ios' ?
{
onBarCodeRead : this._myFunction
}
:
{
// here you can add attribute(s) for other platforms
}
return (
// it is just a part of code for MyView's layout
<RNCamera
ref={ref => { this.camera = ref; }}
style={{ flex: 1, justifyContent: 'flex-end', alignItems: 'center', }}
type={RNCamera.Constants.Type.back}
flashMode={RNCamera.Constants.FlashMode.on}
{...scannerProps}
/>
);
}
}
以一种简单的方式
const InputText= ({required = false , disabled = false, ...props}) =>
(<input type="text" disabled={disabled} required={required} {...props} />);
并像这样使用它
<InputText required disabled/>
<Button {...(isWeb3Enabled ? {} : { isExternal: true })}>
Metamask
</Button>
在 React 中,我们将值作为 Props 从父组件传递到子组件。如果该值为 false,则不会将其作为 props 传递。同样在某些情况下,我们也可以使用三元(条件运算符)。
不定期副业成功案例分享
null
的意思是“表现得好像我根本没有指定它”。对于布尔 dom 属性,true/false 优于重复属性名称/false,例如<input disabled>
编译为React.createElement('input', {disabled: true})
readonly
永远不会被添加,因为 React 需要属性readOnly
(大写的 O)。alt={props.alt || null}
,它应该确保它被删除。false
,但只有null
确保该属性实际上已被删除。Warning: Received `false` for a non-boolean attribute `active`...