元素只是在搜索ReactJS后呈现

时间:2018-04-04 00:02:30

标签: javascript reactjs

发生了什么事?

当我在input上输入一个字母并点击search时,这些元素只会呈现,而不是那样。

发生了什么事?

是否元素在没有任何动作的情况下自动渲染。

我不知道发生了什么......

有人帮帮我吗? 我的代码:

class Pagination extends React.Component {
  constructor() {
    super();

    this.state = {
      elementsPerPage:3,
      currentPage:0,
      peoples:[
        {id:0, name:"Jean"}, 
        {id:1, name:"Jaquinha"}, 
        {id:2, name:"Ricardo"}, 
        {id:3, name:"JaCA"}, 
        {id:4, name:"Letiiicia"}, 
        {id:5, name:"Dai"}, 
        {id:6, name:"Da iIIane"}, 
        {id:7, name:"Tamy"}, 
        {id:8, name:"Tamyresss"},
        {id:9, name:"Tamyres"}, 
        {id:10, name:"Abeu"}, 
        {id:11, name:"Abellll"}
      ],
      input: "",
      filtered: [],
    };

    this.nextPage = this.nextPage.bind(this);
    this.previousPage = this.previousPage.bind(this);
    this.filterNames = this.filterNames.bind(this);
    this.getValueInput = this.getValueInput.bind(this);
  } 
  
  getValueInput(value) {
    this.setState({
      input: value.target.value
    });
  }
    
    
  filterNames() {
    const {peoples} = this.state;
    this.state.filtered = peoples.filter(item => item.name.includes(this.state.input))
    this.setState({
      filtered: this.state.filtered,
      currentPage:0
    });
  } 
  

  elementsOnScreen() {
    const {elementsPerPage, currentPage, filtered} = this.state;
    return filtered
      .map((item) => <li>{item.name}</li>)
      .slice(currentPage*elementsPerPage, currentPage*elementsPerPage + elementsPerPage)
  }

  nextPage() {
    const {elementsPerPage, currentPage, peoples} = this.state;
    
    if ((currentPage+1) * elementsPerPage < peoples.length){
      this.setState({ currentPage: this.state.currentPage + 1 });
      console.log(this.state.currentPage)  
    }
  }
  
  previousPage() {
    const { currentPage } = this.state;
    if (currentPage - 1 >= 0){
      this.setState({ currentPage: this.state.currentPage - 1 });
    }
  }

  render() {
    return (
      <div>
        <input type="text" onChange={ this.getValueInput }></input>
        <button className='search' onClick={this.filterNames}> Search </button>
        <button onClick={this.previousPage}> Previous </button>
        <button onClick={this.nextPage}> Next </button>
        <ul>Names: {this.elementsOnScreen()}</ul>
        <h3>Current Page: {this.state.currentPage}</h3>
      </div>
    );
  }
}

ReactDOM.render(
  <Pagination/>,
  document.getElementById('root')
)
<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="root"></div>

1 个答案:

答案 0 :(得分:1)

问题是您正在渲染filtered但未初始化它。只有在输入或页面更改后才会设置它。如果您将其初始化为与peoples相同,则它看起来有效:

const peoples = [
  {id:0, name:"Jean"}, 
  {id:1, name:"Jaquinha"}, 
  {id:2, name:"Ricardo"}, 
  {id:3, name:"JaCA"}, 
  {id:4, name:"Letiiicia"}, 
  {id:5, name:"Dai"}, 
  {id:6, name:"Da iIIane"}, 
  {id:7, name:"Tamy"}, 
  {id:8, name:"Tamyresss"},
  {id:9, name:"Tamyres"}, 
  {id:10, name:"Abeu"}, 
  {id:11, name:"Abellll"}
];

this.state = {
  elementsPerPage:3,
  currentPage:0,
  peoples,
  input: "",
  filtered: peoples,
};

还需要将分页更改为基于过滤后的数组而不是原始数据:

const {elementsPerPage, currentPage, filtered} = this.state;

if ((currentPage+1) * elementsPerPage < filtered.length){

请参阅下面的演示:

class Pagination extends React.Component {
  constructor() {
    super();

    const peoples = [
      {id:0, name:"Jean"}, 
      {id:1, name:"Jaquinha"}, 
      {id:2, name:"Ricardo"}, 
      {id:3, name:"JaCA"}, 
      {id:4, name:"Letiiicia"}, 
      {id:5, name:"Dai"}, 
      {id:6, name:"Da iIIane"}, 
      {id:7, name:"Tamy"}, 
      {id:8, name:"Tamyresss"},
      {id:9, name:"Tamyres"}, 
      {id:10, name:"Abeu"}, 
      {id:11, name:"Abellll"}
    ];

    this.state = {
      elementsPerPage:3,
      currentPage:0,
      peoples,
      input: "",
      filtered: peoples,
    };

    this.nextPage = this.nextPage.bind(this);
    this.previousPage = this.previousPage.bind(this);
    this.filterNames = this.filterNames.bind(this);
    this.getValueInput = this.getValueInput.bind(this);
  } 
  
  getValueInput(value) {
    this.setState({
      input: value.target.value
    });
  }
    
    
  filterNames() {
    const {peoples} = this.state;
    this.setState({
      filtered: peoples.filter(item => item.name.includes(this.state.input)),
      currentPage:0
    });
  } 
  

  elementsOnScreen() {
    const {elementsPerPage, currentPage, filtered} = this.state;
    return filtered
      .map((item) => <li>{item.name}</li>)
      .slice(currentPage*elementsPerPage, currentPage*elementsPerPage + elementsPerPage)
  }

  nextPage() {
    const {elementsPerPage, currentPage, filtered} = this.state;
    
    if ((currentPage+1) * elementsPerPage < filtered.length){
      this.setState({ currentPage: this.state.currentPage + 1 });
    }
  }
  
  previousPage() {
    const { currentPage } = this.state;
    if (currentPage - 1 >= 0){
      this.setState({ currentPage: this.state.currentPage - 1 });
    }
  }

  render() {
    return (
      <div>
        <input type="text" onChange={ this.getValueInput }></input>
        <button className='search' onClick={this.filterNames}> Search </button>
        <button onClick={this.previousPage}> Previous </button>
        <button onClick={this.nextPage}> Next </button>
        <ul>Names: {this.elementsOnScreen()}</ul>
        <h3>Current Page: {this.state.currentPage}</h3>
      </div>
    );
  }
}

ReactDOM.render(
  <Pagination/>,
  document.getElementById('root')
)
<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="root"></div>