4

Recently I started working on React js16 with Typescript. Moving from angular to react. I am trying to create my own sortable table. Here i am using native JS like code. And I am not sure wether I am doing right or wrong. Cause in angular we were not using native js. In react we can use ref but as per facebook it is having some issues. Another approach like ReactDOM.findNode which is also deprecated i think. So what would be the best approach to do it or whatever I am doing that is fine? I am struggling to find the best approach to do it.

Please see the code written inside showDelete() function. The way i am adding the className and replacing the class name those are correct or any other approach recommended? Sorting logic is not there cause I will do server side sorting.

class CoursePage extends React.Component<CoursePageProps, any> {
    constructor(props: CoursePageProps) {
        super(props);
        this.showDelete = this.showDelete.bind(this);
    }
    showDelete(event: any) {
        let d = document.querySelectorAll('.customTable th');
        let c = document.getElementsByClassName('sortArrow') as HTMLCollectionOf<HTMLElement>;
        for (let i = 0; i < c.length; i++) {
            c[i].style.display = 'none';
        }
        for (let i = 0; i < d.length; i++) {
            d[i].className = d[i].className.replace(' active', '');
        }
        event.currentTarget.className += ' active';
        event.currentTarget.childNodes[1].className += ' fa fa-long-arrow-down';
        event.currentTarget.childNodes[1].style.display = 'inline';
    }
    render() {
        return (
            <div>
                <Custom courses={this.props.courses} showDelete={this.showDelete}/>
            </div>
        );
    }
}
function mapStateToProps(state: any) {
    return {
        courses: state.courses,
    };
}export default connect(mapStateToProps)(CoursePage);

export default class Custom extends React.Component<buttonProps, any> {
    render() {
        const {showDelete, courses} = this.props;
        return (
            <div>
                <table className="table customTable">
            <thead>
                <tr>
                    <th onClick={(e) => showDelete(e)}>Id<i className="sortArrow"/></th>
                    <th onClick={(e) => showDelete(e)}>Name<i className="sortArrow"/></th>
                </tr>
            </thead>
            <tbody>
                ...
            </tbody>
        </table>
            </div>
        );
      }
}
DirtyMind
  • 2,353
  • 2
  • 22
  • 43
  • 1
    What issues are you referring to with ref? – WayneC Dec 15 '17 at 14:55
  • 5
    There is almost never a need to manipulate DOM elements like that, in React you do it differently (React itself will then manipulate DOM elements). Please read [this page](https://reactjs.org/docs/thinking-in-react.html). – xs0 Dec 15 '17 at 15:00
  • Check this https://stackoverflow.com/questions/38093760/how-to-access-a-dom-element-in-react-what-is-the-equilvalent-of-document-getele/38093981#38093981 – Shubham Khatri Dec 15 '17 at 15:10
  • General rule of thumb: if you ever find yourself using refs or DOM manipulation in React, stop and *really, really* think whether there's a better way. They're rarely the right solution. – Joe Clay Dec 15 '17 at 15:12
  • @wgcrouch i am referring this line from doc: Legacy API: String Refs If you worked with React before, you might be familiar with an older API where the ref attribute is a string, like "textInput", and the DOM node is accessed as this.refs.textInput. We advise against it because string refs have some issues, are considered legacy, and are likely to be removed in one of the future releases. If you're currently using this.refs.textInput to access refs, we recommend the callback pattern instead. – DirtyMind Dec 15 '17 at 18:41
  • @ShubhamKhatri can you pls provide code snippet how I can do the same in react way? I am just trying to change the icon at header? or do I need to use third party plugin? I am very new in react so i find it bit complex. – DirtyMind Dec 15 '17 at 18:49

1 Answers1

2

I found the soultion and changed my code accordingly:

class CoursePage extends React.Component<CoursePageProps, any> {
    constructor(props: CoursePageProps) {
        super(props);
        this.state = {
               data : {
                columnName : '',
                sortOrder : '',
                searchText: ''
    }
        };
    }
    sortChanged (e: any, order: string) {
        const Data = this.state.data;
        Data.sortOrder = order.toString().toLowerCase() === 'asc' ? 'desc' : 'asc';
        Data.columnName = e.currentTarget.innerText;
        this.setState({data: Data});   
    }
    _sortClass(filterName: string) {
        return 'fa fa-fw ' + ((filterName === this.state.data.columnName) ? 
        ('fa-sort-' + this.state.data.sortOrder) : 'fa-sort');
    }
    render() {
        return (
            <div>
                <table className="table customTable">
                <thead>
                            <tr>
                                <th onClick={(e) => { this.sortChanged(e, this.state.data.sortOrder); }}>
                                Id
                                    <i className={this._sortClass('Id')}/></th>
                                <th onClick={(e) => { this.sortChanged(e, this.state.data.sortOrder); }}>
                                    Name
                                    <i className={this._sortClass('Name')}/></th>
                                <th onClick={(e) => { this.sortChanged(e, this.state.data.sortOrder); }}>
                                    Address
                                    <i className={this._sortClass('Address')}/>
                                </th>
                            </tr>
                        </thead>
                        <tbody>
                        {this.props.courses.map((course: Course) =>
                    <CourseListRow key={course.id} course={course} />
                )}
                </tbody>
                </table>
            </div>
        );
    }
}
function mapStateToProps(state: any) {
    return {
        courses: state.courses,
    };
DirtyMind
  • 2,353
  • 2
  • 22
  • 43
  • For more details : http://www.dotnetawesome.com/2016/02/server-side-paging-and-sorting-in-react-js.html – DirtyMind Dec 18 '17 at 10:27