REACT-在反应中添加输入切换

时间:2018-08-09 03:51:42

标签: javascript reactjs react-component react-starter-kit vanilla-typescript

  

我正在创建一个React应用,我必须在我的内部添加一个输入切换   标头组件。我尝试添加,但是JavaScript无法正常工作。如果

这是头组件文件。在此组件内部,我已经包含了输入切换条件。我已将JavaScript代码放置在导入文件的正下方。

  

任何人都知道,请检查谢谢。

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import {
  Nav,
  Navbar,
  Collapse,
  DropdownMenu,
  DropdownItem,
  NavbarToggler,
  DropdownToggle,
  UncontrolledDropdown,
} from 'reactstrap';
import { Link, withRouter } from 'react-router-dom';
import Config from '../../../constants/config';
import { SidebarNavItems } from '../Sidebar';
import logoImages from '../../../images/logo.png';
require('./styles.scss');

var allInputs = document.querySelectorAll('.myInput');
allInputs.forEach(function(node) {
    node.addEventListener("click", function(){
      var allHiddenInputs = document.querySelectorAll('.hidden');
      if(allHiddenInputs.length === 0) {
        allInputs.forEach(function(input) {
          input.classList.add("hidden");
          input.classList.add("second");
          input.classList.remove("first");
        });
        node.classList.remove("hidden");
        node.classList.remove("second");
        node.classList.add("first");
      } else {
        allHiddenInputs.forEach(function(input) {
          input.classList.remove("hidden");
        });
      }
    });
});
class Search extends Component {
  constructor(props) {
    super(props);
  }

  render() {

    return (
      <div className="">
        <div className="input-container">
          <input type="password" placeholder="Input 1" className="myInput first" />
          <input type="password" placeholder="Input 2" className="myInput second hidden" />
        </div>
      </div>

    );
  }
}

export default withRouter(Search);

这是我的css文件,已链接到此组件。

.input-container {
  display: flex;
  flex-direction: column;
}
.myInput {
  margin: 10px;
  padding: 5px
}
.first {
  order: 1;
}
.second {
  order: 2;
}
.hidden {
  display: none;
}

enter image description here

4 个答案:

答案 0 :(得分:1)

尝试将代码置于组件生命周期中(例如componentDidMount),然后它将起作用。但是在做出反应时,直接使用DOM节点并不是一个好的解决方案。 更好的方法是这样做:

class Search extends Component {
  constructor(props) {
    super(props);
    this.state = {allInputsHidden: true}; // You can change it later
  }

  render() {

    return (
      <div className="">
        <div className="input-container">
          <input type="password" placeholder="Input 1" className="myInput first" />
          <input type="password" placeholder="Input 2" className={this.state.allInputsHidden ? "myInput second hidden" : "myInput second"} />
        </div>
      </div>

    );
  }
}

此外,您可以使用软件包classnames使它看起来更漂亮

答案 1 :(得分:1)

使用条件渲染来完成此任务。您可以参考此page。将输入组创建为组件,并添加布尔属性以与if条件一起使用。这比添加类要好得多。

function Inputs(props) {
  const isFirst = props.isFirst;
  if (isFirst) {
    return <input type="password" placeholder="Input 1" className="myInput first" />;
  }
  return <input type="password" placeholder="Input 2" className="myInput second" />;
}

ReactDOM.render(
  <Inputs isFirst={true} />,
  document.getElementById('root')
);

并添加一个单击事件以切换isFirst变量的值。

答案 2 :(得分:1)

您可以使用状态来决定要显示哪个元素...

   class Search extends Component {
             constructor(props) {
             super(props);
             this.state = {
             toggleInput1:true,

              }

      render() {

    return (
      <div className="">
        <div className="input-container">
         {this.state.toggleInput1?
          <input type="password" placeholder="Input 1" className="myInput 
           first" />: 
          <input type="password" placeholder="Input 2" className="myInput 
          second hidden" />
     }
        </div>
      </div>

    );
     }
    }

    export default withRouter(Search);

然后在EventListener上更改toogleInput的状态

handleClick = event => {
    this.setState({toggleInput1:!this.state.toggleInput1 });
  };

答案 3 :(得分:1)

我要模拟与您尝试做的事情相同的事情是使用本地状态更新视图。您可以有条件地渲染项目以及每个渲染周期的类名。

class App extends React.Component {
    constructor() {
      super()
      this.inputNames = ['input1', 'input2']
      this.state = {
        hiddenInputs: {
        input1: { hidden: false, first: true },
        input2: { hidden: true, first: false }
      },
      expanded: false
    }
  }
  handleClick(name) {
    const hI = Object.assign({}, this.state.hiddenInputs)
    let expanded = this.state.expanded

    if (expanded && hI[name].first === true) {
      // clicked on the first element, we hide the other
      expanded = false
    } else if (expanded) {
        // clicked on non first item, change order
      this.inputNames.forEach(input => {
        const isSame = input === name
        hI[input].first = isSame
        hI[input].hidden = !isSame
      })
    } else {
        // its not open yet, show the other
        expanded = true
    }

    this.setState({expanded, hiddenInputs: hI})
  }
  render() {
    const { input1, input2 } = this.state.hiddenInputs
    const {expanded} = this.state
    const clsName1 = `myInput${input1.hidden && !expanded ? ' hidden' : ''}${input1.first ? ' first' : ' second'}`;
    const clsName2 = `myInput${input2.hidden && !expanded ? ' hidden' : ''}${input2.first ? ' first' : ' second'}`;
    return (
        <div className="">
        <div className="input-container flex">
          <input type="password" placeholder="Input 1" onClick={this.handleClick.bind(this, 'input1')} className={clsName1} />
          <input type="password" placeholder="Input 2" onClick={this.handleClick.bind(this, 'input2')}  className={clsName2} />
        </div>
      </div>
    );
  }
}

ReactDOM.render(
  <App />,
  document.getElementById('container')
);

CSS:

.flex {
  display: flex;
}
.first {
  order: 0;
}
.second {
  order: 1;
}
.hidden {
  display: none;
}

Fiddle to see it in action