我正在使用导入数据数组的组件模板生成表单字段元素。我希望能够隐藏其中一些元素,并在满足其他元素的标准时显示它们;这在表单字段中相当常见,例如当您选择项目A时,将显示表单字段X,当您选择项目B时,表单字段X将被隐藏。
我在React docs网站上的conditional rendering上读过一些内容,但是这些示例对我正在做的事情并不起作用,尽管“渲染中的预防组件”部分很接近。
我made a Codepen演示我的设置,我想要做的是如果满足第一个字段的条件,则显示第二个字段(在此示例中,第一个字段应输入5个字符)。我已经通过了一个道具来设置最初的隐藏,但我怎样才能找到那个特定的隐藏元素并取消隐藏呢?
// Field data
const fieldData = [{
"type": "text",
"label": "First",
"name": "first",
"placeholder": "Enter first name",
"hidden": false
}, {
"type": "text",
"label": "Surname",
"name": "surname",
"placeholder": "Enter surname",
"hidden": true
}];
// Get form data
class FormData extends React.Component {
constructor(props) {
super(props);
this.state = {
items: props.data
};
}
render() {
let els = this.state.items;
return els.map((el, i) => {
return <Input key={i} params={el} />
});
}
}
// Input builder
class Input extends React.Component {
constructor(props) {
super(props);
// Keep state value
this.state = {
value: '',
valid: false,
hidden: this.props.params.hidden
};
this.handleChange = this.handleChange.bind(this);
}
handleChange(e) {
this.setState({
value: e.target.value,
valid: e.target.value.length < 5 ? false : true
});
}
render() {
// Element attributes
const {type, label, name, placeholder, hidden} = this.props.params;
const isValid = this.state.valid === true ? <span>Valid! Should show Surname field.</span> : <span>Not valid. Should hide Surname field.</span>;
if (!hidden) {
return (
<div>
{label ? <label htmlFor={name}>{label}</label> : null}
<input
type={type}
name={name}
placeholder={placeholder || null}
value={this.state.value}
onChange={this.handleChange}
/>
{isValid}
</div>
);
} else {
return null;
}
}
}
// App
class App extends React.Component {
render() {
return (
<div>
<h1>Show/Hide test</h1>
<p>What we want here is the surname to appear when firstname has a value (say, it has 5 characters) and hide surname when firstname doesn't.</p>
<FormData data={fieldData} />
</div>
);
}
}
ReactDOM.render(
<form>
<App />
</form>,
document.getElementById('app')
);
答案 0 :(得分:5)
您可以lift the state up,Input
的父母将处理状态和验证
您可以有条件地调用surname
属性的“验证器”或任何其他属性,只有它存在并且自己做一个约定,验证方法将得到名称:propertNameValidator
。
因此,例如当您对输入进行循环时,您可以检查是否存在
一个名为surnameValidator
的验证方法,并针对您将传递hidden
的{{1}}道具调用它,如果它不存在,则只需传递Input
。
以下是您的代码的一个小示例:
false
// Field data
const fieldData = [
{
type: "text",
label: "First",
name: "first",
placeholder: "Enter first name",
hidden: false
},
{
type: "text",
label: "Surname",
name: "surname",
placeholder: "Enter surname",
hidden: true
}
];
// Get form data
class FormData extends React.Component {
constructor(props) {
super(props);
this.state = {
items: props.data.map(el => ({...el, value: ''})) // add the value property
};
}
onInputChange = (inputId, value) => {
const { items } = this.state;
const nextState = items.map((item) => {
if (inputId !== item.name) return item;
return {
...item,
value,
}
});
this.setState({ items: nextState });
}
surnameValidator = () => {
const { items } = this.state;
const nameElement = items.find(item => item.name === 'first');
return nameElement && nameElement.value.length >= 5
}
render() {
let els = this.state.items;
return (
<div>
{
els.map((el, i) => {
const validator = this[`${el.name}Validator`];
return (
<Input
key={i}
{...el}
inputId={el.name}
hidden={validator ? !validator() : el.hidden}
onInputChange={this.onInputChange}
/>
);
})
}
</div>
)
}
}
// Input builder
class Input extends React.Component {
handleChange = ({ target }) => {
const { inputId, onInputChange } = this.props;
onInputChange(inputId, target.value);
}
render() {
// Element attributes
const { type, label, name, placeholder, hidden, value } = this.props;
return (
<div>
{
hidden ? '' : (
<div>
{label ? <label htmlFor={name}>{label}</label> : null}
<input
type={type}
name={name}
placeholder={placeholder || null}
value={value}
onChange={this.handleChange}
/>
</div>
)
}
</div>
);
}
}
// App
class App extends React.Component {
render() {
return (
<div>
<h1>Show/Hide test</h1>
<p>
What we want here is the surname to appear when firstname has a value
(say, it has 5 characters) and hide surname when firstname doesn't.
</p>
<FormData data={fieldData} />
</div>
);
}
}
ReactDOM.render(
<form>
<App />
</form>,
document.getElementById("app")
);
如果您已经创建了元素并且只想隐藏/显示它,那么您可以有条件地添加或删除隐藏它的CSS <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>
。
class
答案 1 :(得分:0)
如果我没有弄错,你想要的是有条件地显示或隐藏输入元素。看看这是否有帮助。
render() {
// Element attributes
const {type, label, name, placeholder, hidden} = this.props.params;
const isValid = this.state.valid === true ? <span>Valid! Should show Surname field.</span> : <span>Not valid. Should hide Surname field.</span>;
if (!hidden) {
return (
<div>
{label ? <label htmlFor={name}>{label}</label> : null}
<input
type={type}
name={name}
placeholder={placeholder || null}
value={this.state.value}
onChange={this.handleChange}
/>
{this.state.valid && <input placeholder="add surname" />}
</div>
);
} else {
return null;
}
}