Search code examples
javascriptreactjscomponents

React on click event order array of data passing in the component


I'm new to React and I'd like some help please. I'm having a button and a component inside my app.js which is the main file

import React from 'react'

const App = () =>  {

  const {data, loading, error} = useQuery(GET_DATA, {
    variables: {...}
  })

  console.log(data)

  state = {
    clickSort: false
  }   

  let clickSort = () => {
    this.setState({
      clickSort: true
    })
  }

  return (
    <div className="myApp">
          <button onClick="{this.clickSort}">Click Me</button>

        <div className="myClass">
          <FooComponent fooData={data} clickSort={this.state.clickSort} />
        </div>
</div>
  )
}

What I want to do is when I click the button to sort the array of data I'm rendering in my component in a desc order. I was thinking of passing another parameter like a flag in the component, but I'm not sure how can I do this


Solution

  • If both of your components (<Button /> and <List />) are wrapped within common parent (<Parent />) you may employ the concept, known as lifting state up

    Essentially, it is binding event handler within one of the child component's props (onSort() of <Button />) to the callback within parent (handleSort() of <Parent />), as well as binding dependent child prop (isSorted of <List />) to the state variable of common parent (sorted of <Parent />).

    With that, you simply keep track of sorted flag within parent state (using useState() hook) and once handleSort() is triggered, it modifies that flag and consequent re-render of dependent components (<List />) takes place:

    const { render } = ReactDOM,
          { useState } = React
          
    const sampleData = ['itemC', 'itemA', 'itemD', 'itemB']      
          
    const Button = ({onSort}) => <button onClick={onSort}>Sort it</button>
    
    const List = ({listData, isSorted}) => { 
      const listToRender = isSorted ? listData.sort((a,b) => b > a ? 1 : -1) : listData
      return (
        <ul>
          {listToRender.map((li,key) => <li {...{key}}>{li}</li>)}
        </ul>
      )
    }
    
    const Parent = () => {
      const [sorted, setSorted] = useState(false),
            handleSort = () => setSorted(true)
      return (
        <div>
          <Button onSort={handleSort} />
          <List listData={sampleData} isSorted={sorted} />
        </div>
      )
    }
    
    render (
      <Parent />,
      document.getElementById('root')
    )
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.11.0/umd/react-dom.production.min.js"></script><div id="root"></div>