为什么在setState之后我的组件不重新渲染?

时间:2019-04-05 09:26:00

标签: javascript reactjs

我有一个作为道具发送给子组件的函数。当函数被调用并且状态在函数中被更新时,父组件不会被更新。为什么是这样?

class Admin extends React.Component{
    constructor(props) {
        super(props);
        this.viewOrderCommand=this.viewOrderCommand.bind(this);
        this.state = {
            cmd: 0,
            stillLoading: true
        };
    }

    viewOrderCommand(cmd, id) {   
        if (id > 0) {
            this.setState({cmd, id});
        }     
    }
    render() {
        const { isLoading, apiToken } = this.props;
        let userInformationNode = <LoadingSpinner isLoading={true} />;
        console.log('OrderSearchData this.state',this.state.cmd);
        if (this.state.cmd && this.state.cmd > 0) {
            userInformationNode =<NewUser viewOrderCommand={this.viewOrderCommand} id={this.state.id} apiToken={apiToken} />;
        } else {
            userInformationNode = <CurrentUser apiToken={apiToken} viewOrderCommand={this.viewOrderCommand}/>;
        }
        if (isLoading) {
            userInformationNode=undefined;
        }
        return (
            <Tabs defaultActiveKey="current" id="admin-user-tabs">
                <Tab eventKey="current" title="Current Users">
                    {userInformationNode}
                </Tab>
                <Tab eventKey="new" title="New Users">
                    <NewUser apiToken={this.props.apiToken}  />
                </Tab>
                <Tab eventKey="create" title="Create New User">
                    <CreateUser apiToken={this.props.apiToken} />
                </Tab>    
            </Tabs>
        );
    }
}
export default Admin;¨

这是子组件,我在其中从Admin组件中调用函数viewOrderCommand。

import React from 'react';
import NPPanel from '../../NPPanel';
import { Col, Row } from 'react-bootstrap';


import "react-table/react-table.css";
import 'react-select/dist/react-select.css';
import 'bootstrap/dist/css/bootstrap.css';

import constants from '../.././util/constants';
import axios from 'axios';
import { getFilteredData, setDataForExpansion, getExpander } from '../../gridHelpers/gridHelpers';
import NPHelpButton from '../../NPHelpButton';
import NPReactTable from '../../NPReactTable';
import LoadingSpinner from '../../LoadingSpinner';


import './style.less';


const { API_BASE_URL } = constants;

class CurrentUser extends React.Component{
        constructor(props) {
          super(props);    
          this.tell = this.tell.bind(this);
          this.state = { users: undefined, loaded:false };
          this.getUsers = this.getUsers.bind(this);
          this.handleSelectChange = this.handleSelectChange.bind(this);
          this.getUsers('', true);
      }

        tell(txt, row){
          setDataForExpansion(txt, row, this.props.apiToken, this);
        }

        clearCurrentExpandforAll(){
          let d = getFilteredData(this.reactTable.getReactTable());
          this.currentExpand = '';
          d.forEach(dt => {
              dt.TAG = undefined;
          });
        }

        handleSelectChange(evt, item, row){
          if (item && row && row.original) {
            let selIndex=evt.currentTarget.selectedIndex;
            evt.currentTarget.selectedIndex=0;
            this.props.viewOrderCommand(selIndex, row.original.Id);

            }
          }


        getcolumns() {
            const helpNode = (
                <div>
                ...
                </div>
              );



        return ([

            {
                Header: "User information",
                headerStyle: { background: '#dedede' },
                columns: [
                      {
                        Header: "",
                        maxWidth: 30,
                        Filter: ({ filter, onChange }) =>
                            <NPHelpButton content={helpNode} title="Help" />,
                            Cell: (row) =>
                            {
                             console.log('row',row);
                              return <span>
                              <select  className='tst myopt handy' onChange={evt => { this.handleSelectChange(evt, evt.target.value, row, this);}}>
                                <option value="">...</option>
                                <option value="CreateNew">Create new</option>
                                <option value="Edit">Modify this user</option>  
                              </select>
                            </span>
                            } 

                    },
                    {
                        Header: "Username",
                        accessor: "Email",
                    },
                    {
                      expander: true,
                      width: 35,
                      Expander: ({ isExpanded, ...row }) =>
                      getExpander(row,'ClientCodeRegional',this,isExpanded),
                      style: {
                          cursor: "pointer",
                          textAlign: "center",
                          userSelect: "none"
                      },
                    },
                ]
            },

        ]);
    }

    getUsers() {

      const header = {
          'Authorization': 'Bearer ' + this.props.apiToken,
          'Accept': 'application/octet-stream'
      };

      let self = this;
      self.setState({ isLoading: true });

      axios.get(API_BASE_URL + 'Admin/GetUsers', { headers: header })
          .then(result => {
            console.log(result.data);
              const users = result.data.filter(item => {
                return item.Settings && item.Settings.HasAccess === true;
              })
              self.setState({isLoading: false, loaded: true, users: users, expanded: {} });
          }).catch(response => { });

  }


    render(){
      const users = this.state.users;
      if (!users || this.state.isLoading) {
          return <LoadingSpinner isLoading={true} />
      }

        return(


            <NPPanel>
                <Row>
                  <Col sm={12}>
                  <Row>

                    <Col sm={12}>
                    {this.state.loaded?
                        <NPReactTable
                            className="np-react-table"                        
                            data={users}
                            ref={(r) => { this.reactTable = r }}
                            columns={this.getcolumns()}
                            defaultFilterMethod={(filter, row) =>
                              ((row[filter.id] || '').toString().toUpperCase().includes(filter.value.toUpperCase()))}
                            filterable
                            filterAll
                            defaultPageSize={10}
                            // Controlled props
                            sorted={this.state.sorted}
                            page={this.state.page}
                            pageSize={this.state.pageSize}
                            expanded={this.state.expanded}
                            resized={this.state.resized}
                            filtered={this.state.filtered}
                              // Callbacks
                              onSortedChange={sorted => this.setState({ sorted, expanded: {} })}
                              onPageChange={
                                  page => {
                                      this.clearCurrentExpandforAll();
                                      this.setState({ page, expanded: {} });
                                  }

                              }                            
                              onPageSizeChange={(pageSize, page) => {
                                  this.clearCurrentExpandforAll();
                                  this.setState({ page, pageSize, expanded: {} });
                              }
                              }
                              onResizedChange={resized => this.setState({ resized })}
                              onFilteredChange={filtered => {
                                  //this.clearCurrentExpandforAll();
                                  this.setState({ filtered, page: 0, expanded: {} })
                              }
                              }
                              SubComponent={row => {
                                  let r = row.original;
                                  let t = 'EXP_' + r.TAG;
                                  if (r.TAG && r.TAG !== '' && r[t]) {
                                      return r[t];
                                  }
                              }
                              }

                        />
                        :null
                        }
                    </Col>

                </Row>
                  </Col>
                </Row>
              </NPPanel>
        ); 
    }
}

export default CurrentUser;

当我调试代码时,我可以确定该函数已被调用且状态已设置,但从未进行过重新渲染。我希望管理组件呈现NewUser组件而不是CurrentUser。类似的事情在我的代码的另一处完成,并且在那里起作用。

2 个答案:

答案 0 :(得分:1)

编辑:

您的问题可能是因为未正确设置cmd。看来您可能需要这样做:

this.setState({cmd: id});

答案 1 :(得分:0)

这不是错字吗?

viewOrderCommand(cmd, id) {   
    if (id > 0) {
        this.setState({cmd, id}); // is it supposed  to be {cmd: id}  ? 
    }     
}