cpt_3n0x
cpt_3n0x

Reputation: 55

React- Props filtering best practice

I am an intermediate developer on React and I would like to have advice on the best practice to implement props's filtering.

Indeed, I realize that I am very limited when I want to sort these props:

  1. Do I have to put these props in the state and then display / sort the state
  2. Is there a method to display and sort a table from the props directly ?

Example :

app.js

@connect(({ events }) => ({ events }))
class EventList extends React.Component {
 constructor(props) {
    super(props);
    this.state = {
    };
  }

  componentDidMount() {
    const { dispatch } = this.props
    dispatch({type: 'events/GET_ALL_EVENTS'})
  }

  render() {
    const { events } = this.props
    const { allEvents } = events

    return (
      <div>
        <div className="card">
           <div className="card-body">
              <EventsAfter events={allEvents} />
           </div>
         </div>
      </div>
    )
  }
}

export default EventList

EventsAfter.js

class EventAfter extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      dateSort: "next_3_day",
    };
  }

  sortDate = value=> {
    this.setState({ dateSort: value.target.value })
    /* NEED TO SORT PROPS ARRAY OF EVENTS HERE */
  }

  render() {
    const { events } = this.props
    const { dateSort } = this.state

    return (
      <div>
        <div className="row">
          <div className="col-lg-12">
            <div>
              <div style={{display:"inline-block", paddingBottom:'10px'}}>
                <Radio.Group size="default" value={dateSort} onChange={this.sortDate}>
                  <Radio.Button value="next_3_day">Les trois prochains jours</Radio.Button>
                  <Radio.Button value="this_week">Cette semaine</Radio.Button>
                  <Radio.Button value="next_week">La semaine prochaine</Radio.Button>
                </Radio.Group>
              </div>

            </div>
          </div>
        </div>
        <div className="air__utils__scrollTable">
          <Table
            columns={[
              {
                title: 'Evenements',
                dataIndex: 'name',
                key: 'name',
                className: 'text-gray-6',
              },
              {
                title: 'Date',
                dataIndex: 'date',
                key: 'date',
                className: 'text-gray-6',
                render: d => {
                  return <Moment format='LLL'>{d}</Moment>
                },
                sorter: (a, b) => a.date.size - b.date.size,
              }
            ]}
            dataSource={events}
            scroll={{ x: '100%' }}
          />
        </div>
      </div>
    )
  }
}

export default EventAfter

In the first file, I send the events (table) to the child component 'EventAfter'. In the second file, when the user clicks on a radio button, it changes the sort state (next_3_day, this_week, next_week).

I would like (but I can't), sort and display only those events that meet a criterion without modifying the original table (so that I can display the entire table).

Can you help me ? Do I use react correctly on this part or does a pattern exist ?

Thank you very much, it would help me a lot.

Upvotes: 0

Views: 369

Answers (2)

Damian Green
Damian Green

Reputation: 7495

Your table column already has a sorter function for allowing the reordering so you don't need to store the sorted values in state.

Although you have something called dateSort: "next_3_day" which ostensibly seems like you want to filter your data set (not just sort), which is a different question.

It looks like you want to do the following:

dataSource={this.state.dateSort === 'next_3_day' ? events.filter(x=>x.date > new Date((new Date()).getTime() + (60*60*24*3))):this.events}

[and extend for the other 3 dateSorts` options]

Personally I wouldn't store the filtered value in state, I would just create a function that filters it.

You're setting the state with dateSort so the component will re-render and it will allow for new data to be passed from the parent component.

I'd also suggest using https://date-fns.org/ for simplified date arithmetic here.

I can't see the type of your input data but a.date.size seems a bit suspicious to me. Does your sorting currently work with this value?

Upvotes: 1

Dmitry Reutov
Dmitry Reutov

Reputation: 3032

In your case better call it filtering instaed of sorting, otherwise sounds bit confusing, sorting normally means ordering...

But yes, it is better to create a property in state, which will contain filtered or ordered array.

this.setState({ 
  dateSort: value.target.value 
  eventsFiltered: this.props.event.filter(someFilterFunc)
})

and pass to children components this.state.eventsFiltered

Upvotes: 0

Related Questions