Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何使渲染与分页时的状态同步?单击“反应”?_Javascript_Reactjs - Fatal编程技术网

Javascript 如何使渲染与分页时的状态同步?单击“反应”?

Javascript 如何使渲染与分页时的状态同步?单击“反应”?,javascript,reactjs,Javascript,Reactjs,我创建了一个建议搜索,并构建了它来分解基于当前页面的获取。状态为console.loged正确,但呈现是一个页面单击事件。这显然不是我们想要的行为。看起来状态更新得很好。我尝试过以不同的方式重构代码,甚至尝试过这个.forceUpdate 这是密码 SearchOrderBar.js import React, { Component } from "react"; import {Input, Label, Table, Icon, Header, Menu} from 'semantic-u

我创建了一个建议搜索,并构建了它来分解基于当前页面的获取。状态为console.loged正确,但呈现是一个页面单击事件。这显然不是我们想要的行为。看起来状态更新得很好。我尝试过以不同的方式重构代码,甚至尝试过这个.forceUpdate

这是密码

SearchOrderBar.js

import React, { Component } from "react";
import {Input, Label, Table, Icon, Header, Menu} from 'semantic-ui-react';
import "./SearchOrderBar.css";
// import { resolve } from "dns";
// import PropTypes from 'prop-types';
import Pagination from '../Search/Pagination';


class SearchOrderBar extends Component {
  constructor(props) {
    super(props);
    this.text = "";
    this.state = {
      suggestions: [],
      addToQuery: false,
      Query: [],
      pagesNeeded: 0,
      page: 1
    };
    let searchTerm = null;
    const {pageLimit = null, keyTimer = null, } = props;
    this.pageLimit = typeof pageLimit === 'number' ? pageLimit : 10;
    this.handlePageClick = this.handlePageClick.bind(this);
    this.fetchCallBack = this.fetchCallBack.bind(this);

    // this.addToQuery = this.addToQuery.bind(this);  
    this.keyUpHandler = this.keyUpHandler.bind(this);
    this.keyDownHandler = this.keyDownHandler.bind(this);
  }
  handlePageClick(page){
    this.forceUpdate();
    this.setState({
      page: page
    })
    this.fetchCallBack();
  }
  //This fetch should be called in a dynamic switch case

  fetchCallBack() {
    let y = this.pageLimit;
    let x =  this.state.page > 1 ? (this.pageLimit*this.state.page) - this.pageLimit : 0;
    // Return a promise
    return new Promise((resolve, reject) => {
      let searchTerm = this.searchTerm;
    return fetch(`http://localhost:5000/api/searchorders/${searchTerm}/${x}/${y}`)
      .then(res => {
        if (!res.ok) {
            throw res;
          }
          // Convert serialized response into json
          return res.json()
        }).then(data => {
            //Use data
            let searchTerm = data.map(data => {
                let rData = {};
                rData = data;
                return rData;
            })
            this.item = searchTerm;
            //console.log('here from callback')
           this.setState({
             suggestions: []
           })
            return searchTerm;
      }).then( data => {
        // console.log(this.totalRecords)sd
        //console.log(data)
      if (searchTerm.length === 0) {
        this.setState({
          suggestions: [],
          rangeCount_URL: `http://localhost:5000/api/searchorderscount/${searchTerm}`
        });
      } else {
        const suggestions = data.filter(function(v){
            if(Object.values(v).includes(searchTerm.toLowerCase()) !== -1 || Object.values(v).includes(searchTerm.toUpperCase()) !== -1){
                return v
            }
        })
        console.log(suggestions)
        this.text = searchTerm;
        this.setState({  suggestions: suggestions.sort()});
      }
    })
    })
  }
  pageCountCallBack(){
    return new Promise((resolve, reject) => {
      let searchTerm = this.searchTerm;
    return fetch(`http://localhost:5000/api/searchorderscount/${searchTerm}/`)
      .then(res => {
        if (!res.ok) {
            throw res;
          }
          // Convert serialized response into json
          return res.json()
        }).then(data => {
            //Use data
            let searchTerm = data.map(data => {
                let rData = {};
                rData = data;
                return rData;
            })
            this.item = searchTerm;
           // console.log('here from Page Count callback')
            this.renderSuggestions();
            resolve(searchTerm)
      })
    })
  }

  keyUpHandler = (e) => {
    if(e.target.value.length >= 3){
   this.keyTimer = setTimeout(this.countFetch(e), 1500);
    } else {
      this.setState(() => {
        return {
        suggestions : [],
        pagesNeeded : 0
        }
      })
      clearTimeout(this.keyTimer);
    }
  }
  keyDownHandler = (e) => {
    clearTimeout(this.keyTimer);
   }
  //Any time text is changed in the text field 
  countFetch = (e) => {
    const value = e.target.value;
    this.searchTerm = value;

      this.pageCountCallBack().then(data => {
        const totalRecords = data[0].rows;
        this.setState(() => {
          return {pagesNeeded : Math.ceil(totalRecords / this.pageLimit)}
        })
        //console.log("total" + totalRecords);
        //console.log("page limit"+this.pageLimit);
        //console.log("Needed" + this.state.pagesNeeded );
      })
    this.fetchCallBack();
  }

  renderSuggestions() {
    //const { suggestions } = this.state;
    const tableStyle = { 
      'tableLayout': 'fixed',
      'overflowWrap': 'break-word'
    }
    return (
      <Table style={tableStyle} celled>
        {this.state.suggestions.length === 0 ?
        (<Table.Body>
          <Table.Cell colSpan="7">
            <div className="ui fluid warning icon message">
              <Icon name="exclamation triangle" size="huge" color="orange"/>
              <div className="content">
                <Header>No Records Found</Header>
                <p>Try Seaching by one of the following:</p>
                <ul>
                    <dt>Name</dt>
                    <dt>Order Number</dt>
                    <dt>Address (Shipping or Billing )</dt>
                    <dt>Phone Number</dt>
                    <dt>Email</dt>
                </ul>
              </div>
            </div>
          </Table.Cell>
        </Table.Body>)
        : (
          <>
          <Table.Header>
            <Table.Row>
              <Table.HeaderCell>Order#</Table.HeaderCell>
              <Table.HeaderCell>Billing Address</Table.HeaderCell>
              <Table.HeaderCell>Shipping Address</Table.HeaderCell>
              <Table.HeaderCell>Email</Table.HeaderCell>
              <Table.HeaderCell>Phone Number</Table.HeaderCell>
              <Table.HeaderCell>Sales Channel</Table.HeaderCell>
              <Table.HeaderCell>Order Date</Table.HeaderCell>
            </Table.Row>
        </Table.Header>
        <Table.Body>
          {this.state.suggestions.map((item, index) => (
            <Table.Row className="hoverRow"> 
              <Table.Cell  key={index} onClick={() => this.addToQuery(item)}>
              {item.customerPO}
              </Table.Cell>
              <Table.Cell>
                {item.billToAddress}
              </Table.Cell>
              <Table.Cell>{item.shipToAddress}</Table.Cell>
              <Table.Cell>{item.email}</Table.Cell>
              <Table.Cell>{item.phone}</Table.Cell>
              <Table.Cell>{item.customerContact}</Table.Cell>
              <Table.Cell>{item.dateCreated}</Table.Cell>
            </Table.Row>
          ))}
        </Table.Body>
        </>
        )
    }
      <Pagination key={this.state.pagesNeeded} tableCols="7" pagesNeeded={this.state.pagesNeeded} btnLimit={5} pageClick={this.handlePageClick} currPage={this.state.page} pageLimit={this.pageLimit}/>
      </Table>
    );
  }
  handleIconClick(){
    console.log('icon clicked ' + this.state.Query )
  }
  render() {
      const {text} = this.state
      //console.log(this.state)
    return (
        <>
      <div className="App-Component">
        <div className="App-Search">
          <Input icon={{ name: 'search', circular: true, link: true, onClick: () => this.handleIconClick() }} placeholder="Search" value={text} type="text" onKeyUp={this.keyUpHandler} onKeyDown={this.keyDownHandler} className="App-Search"/>
          {this.renderSuggestions()}
        </div>
      </div>
      </>
    );
  }
}
export default SearchOrderBar;

这是分页,但我认为这对解决方案来说并不重要。它与页面按钮单击相关

import React, {Component} from 'react';

import {Input, Label, Table, Icon, Header, Menu} from 'semantic-ui-react'

/**
 * Helper Method for creating a range of Numbers 
 * Range )(                                                                  )
 */
const range = (from, to, step = 1) => {
  let i = from;
  const range = [];

  while (i<=to) {
    range.push(i);
    i+=step;
  }
}
export default class Pagination extends Component {

    constructor(props){
        super(props)
          const { totalRecords = null, pageNeighbours = 0, rangeCount_URL = this.props.rangeCount_URL, pageArray = [] } = props;
          this.pageArray = typeof pageArray === 'array' ? pageArray : [];
    }
renderPagination = () => {
  //console.log("hello from pagination");
  let n = this.props.pagesNeeded;
  let pArray = [];
  let page = this.props.currPage;

  //console.log(n)
  if (page > 1){
    pArray.push(<Menu.Item as='a' icon onClick={() => this.props.pageClick(page-1)}>
              <Icon name='chevron left' />
            </Menu.Item>)
  }
  for(let i = (page >1 ? page-1: page); pArray.length <  (page > this.props.btnLimit ? this.props.btnLimit+1 : this.props.btnLimit); i++){
    //console.log(i);
    pArray.push(<Menu.Item index={i} className={i == page ? 'active' : ''} onClick={() => this.props.pageClick(i)} as='a'>{i}</Menu.Item>)
  }
  if (page < n){
    pArray.push(<Menu.Item as='a' icon onClick={() => this.props.pageClick(page+1)}>
              <Icon name='chevron right' />
            </Menu.Item>)
  }
  this.pageArray = pArray;
  return pArray;
}

    render(){
      const pageCount = (() => {
        const totalRecords = this.totalRecords;
        if(totalRecords > 0){
          return (this.totalPages = Math.ceil(this.totalRecords / this.props.pageLimit))
        }
      })();
      //console.log(this.pageArray);
        return(
          <Table.Footer>
            { this.props.pagesNeeded > 1 &&
              <Table.Row>
              <Table.HeaderCell colSpan={this.props.tableCols}>
                <Menu floated='right' pagination>
                  {this.renderPagination()}
                </Menu>
              </Table.HeaderCell>
              </Table.Row>
            } 
            </Table.Footer>
        )

    }
}
在调用fetchCallBack时,this.state.page尚未更新,因为setState是异步调用的,这就是它使用旧值的原因。试试这个:

handlePageClick(page) {
  this.setState({ page }, this.fetchCallBack);
}
允许您在下一次迭代中运行函数。

在调用fetchCallBack时,this.state.page尚未更新,因为setState是异步调用的,这就是它使用旧值的原因。试试这个:

handlePageClick(page) {
  this.setState({ page }, this.fetchCallBack);
}
允许您在下一次迭代中运行函数。

setState是批处理的,并异步调用,这意味着当您调用此.setState{page}时,在fetchCallBack中读取this.state.page可能会得到旧页而不是新页

或者直接将页面传递给fetchCallBack

并从中读取页面,而不是直接从州中读取

或者从setState开始调用它,setState是一个回调,在状态被更新后,react将立即调用它

this.setState({ page }, this.fetchCallBack);
setState被批处理并异步调用,这意味着当您调用this.setState{page}时,在fetchCallBack中读取this.state.page可能会得到旧页而不是新页

或者直接将页面传递给fetchCallBack

并从中读取页面,而不是直接从州中读取

或者从setState开始调用它,setState是一个回调,在状态被更新后,react将立即调用它

this.setState({ page }, this.fetchCallBack);

这也解决了我的问题,而且更详细。谢谢你更深入的解释。只有一个人可以得到答案,因为我使用了上面的代码,所以我必须选择他的答案。但我感谢你的深入解释,这也是我通常寻找的。这也会解决我的问题,更详细,谢谢你的深入解释。只有一个人可以得到答案,因为我使用了上面的代码,所以我必须选择他的答案。但我感谢你更深入的解释,这也是我通常寻找的。