繁体   English   中英

React.js - 显示/隐藏组件中动态生成的元素

[英]React.js - Show/Hide dynamically generated elements from component

我正在使用导入数据数组的组件模板生成表单字段元素。 我希望能够隐藏其中一些元素,并在满足其他元素的标准时显示它们; 这在表单字段中相当常见,例如,当您选择项目A时,表单字段X出现,当您选择项目B时,表单字段X将被隐藏。

我已经在React docs网站上阅读了很多关于条件渲染的内容,但是这些示例并不适用于我正在做的事情,尽管“渲染中的预防组件”部分很接近。

做了一个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')
  );

您可以提升状态,以便Input的父级处理状态和验证。
您可以有条件地调用surname属性的“验证器”或任何其他属性,只有它存在并且自己执行约定,验证方法将获得名称: propertNameValidator
因此,例如当您对输入进行循环时,您可以检查是否存在名为surnameValidator的验证方法,并针对您将传递Inputhidden prop进行调用,如果它不存在surnameValidator传递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") ); 
 <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> 

如果您已经创建了元素并且只想隐藏/显示它,那么您可以有条件地添加或删除隐藏它的CSS class

<input className={`${!isValid && 'hide'}`} />

如果我没有弄错,你想要的是有条件地显示或隐藏输入元素。 看看这是否有帮助。

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;
      }
 }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM