简体   繁体   中英

Implementation of fixed-data-table-2 sorting using pre-existing redux store?

Thanks in advance for any information or pointers you may have for me.

I'm relatively new to react. I've inherited a pre-existing project which I've been working on for a client for a few weeks now and all is going well until now. I've hit a wall with a feature I need to add to the project.

So the project uses the fixed-data-table-2 library and is displaying a very simple table with 2 columns one a checkbox and the other the name of a file.

Basically the client has asked me to allow them to be able to sort the names of the files alphabetically on click on a header col in both directions ASC/DESC.

I could just use a different library which I would have done that auto includes this sorting but the client has restricted me to use this library as it is used in all their existing tools and so on...

I've been using the example libraries to try and implement it but i'm getting so confused with the data they are using in their example. Since I'm using a redux store: https://github.com/schrodinger/fixed-data-table-2/blob/master/examples/SortExample.js

Would any kind person out there with Redux experience give me a pointer or an example of this being done.

My project is using Containers (Logic), (Components UI). Using reducers to mutate the state which are called with actions.

I don't feel comfortable sharing the code of this project as I don't own the code myself.

I understand the moving parts but the example given in the docs are confusing. Again thank you for any advice in advance.

EDIT I'm a bit all over the place with this one. Again I'm new to React and would love some help in getting this task over the line.

The grab terminology is used by the client, its just a zip file.

So this is my header cell component which is used to display the direction of the arrow of which the data id sorted:

import PropTypes from 'prop-types';
import React, { Component } from 'react';
import {Cell} from 'fixed-data-table-2';

var SortTypes = {
  ASC: 'ASC',
  DESC: 'DESC'
};

function reverseSortDirection(sortDir) {
  return sortDir === SortTypes.DESC ? SortTypes.ASC : SortTypes.DESC;
}

class HeaderCellSelected extends Component {

  constructor(props, context) {
    super(props, context);

    this._onSortChange = this._onSortChange.bind(this);
  }

  render() {
    const {onSortChange, sortDir, children, ...props} = this.props;
    return (
      <Cell {...props}
            sortDir={this.props.sortDir}
            headerCell={this.props.headerCell}
      >
      <a onClick={this._onSortChange}>
          {children} {sortDir ? (sortDir === SortTypes.DESC ? '↑' : '↓') : ''}
      </a>
  </Cell>
    );
  }

  _onSortChange(e) {
    e.preventDefault();

    if (this.props.sortGrabs) {
      this.props.sortGrabs(
        this.props.columnKey,
        this.props.sortDir ?
          reverseSortDirection(this.props.sortDir) :
          SortTypes.DESC
      );
    }
  }
}

HeaderCellSelected.propTypes = {
  headerCell: PropTypes.string.isRequired,
  sortDir: PropTypes.string.isRequired,
  sortGrabs: PropTypes.func.isRequired,
  columnKey: PropTypes.string.isRequired
};

export default HeaderCellSelected;

This is my cotainter:

import PropTypes from 'prop-types';
import React from 'react';
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';
import * as actions from '../grabsTableActions';
import HeaderCellSelected from './SortHeaderCellComponent';

export const HeaderCellContainer = (props) => {

  return (
    <HeaderCellSelected
      headerCell={props.headerCell}
      sortDir={props.sortDir}
      sortGrabs={props.actions.sortGrabs}
      columnKey={"fileName"}
    />
  );
};

function mapStateToProps(state) {
  return {
    headerCell: state.grabsTable.sortCol,
    sortDir: state.grabsTable.sortDir
  };
}

function mapDispatchToProps(dispatch) {
  return {
    actions: bindActionCreators(Object.assign({}, actions), dispatch)
  };
}

HeaderCellContainer.propTypes = {
  actions: PropTypes.object.isRequired,
  headerCell: PropTypes.string.isRequired,
  sortDir: PropTypes.string.isRequired
};

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(HeaderCellContainer);

I've also added toe action to my reducer: for now I just want it to sort in one direction I will put in the reverse functionality later on:

case SORT_GRABS: {
      let grabs = state.grabs.map(grab => grab);
      grabs = grabs.sort(function(a, b){
        var valueA=a[action.columnKey].toLowerCase(), valueB=b[action.columnKey].toLowerCase();
        if (valueA < valueB){
          return -1;
        }
        if (valueA > valueB){
          return 1;
        }
        return 0;
      });
      return {...state, grabs};
    }
    default:
      return state;

And I'm including my header cell component in the table component like mentioned above.

I would love for some help with the following errors:

React does not recognize the headerCell prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase headercell instead. If you accidentally passed it from a parent component, remove it from the DOM element.

I have 3 errors in total all related to props not being recognized.

Please be patient with me as I'm just working with react a few weeks so apologies if I'm using the state and props incorrectly and I know I'm defiantly not following the propTypes scoping correctly.

Just a last point for now, when I click the column header, I am calling the SORT_GRABS action which calls my reducer but nothing happens. Thanks for any help in advance.

The example you are linking seems to be quite straight forward. They have created a component called SortHeaderCell that you can define for your columns and pass down to the Column component as a prop. The SortHeaderCell requires a onSortChange prop function that you have to implement. The data that you are storing within your redux store can be passed down to the Column component via the prop called cell . Here you pass down the already sorted data list.

        <Column
          columnKey="id"
          header={
            <SortHeaderCell
              onSortChange={this._onSortChange}
              sortDir={colSortDirs.id}>
              id
            </SortHeaderCell>
          }
          cell={<TextCell data={sortedDataList} />}
          width={100}
        />

So what you have to do:

  1. you described there is already a table! Easy enough! Check out what is passed down via the cell prop. This is your data array from the redux store!

  2. write a onSortChange function following the github example that calls a redux action to update the data (set the sorted list as the redux state)

  3. create a SortHeaderCell component that can be clicked and is calling your onSortChange function to change the redux state.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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