Реагировать на щелчок по порядку событий, массив данных, передаваемых в компоненте - PullRequest
1 голос
/ 11 февраля 2020

Я новичок в React и мне нужна помощь, пожалуйста. У меня есть кнопка и компонент внутри моего приложения. js, который является основным файлом

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>
  )
}

Что я хочу сделать, это когда я нажимаю кнопку, чтобы отсортировать массив данных, я рендеринг в моем компоненте в порядке des c. Я думал о передаче другого параметра, такого как флаг в компоненте, но я не уверен, как я могу это сделать

Ответы [ 3 ]

1 голос
/ 12 февраля 2020

Если оба ваших компонента (<Button /> и <List />) заключены в общий родительский элемент (<Parent />), вы можете использовать концепцию, известную как подъем состояния вверх

По сути, это связывающий обработчик событий в одном из реквизитов дочернего компонента (onSort() из <Button />) с обратным вызовом внутри родителя (handleSort() из <Parent />), а также связывающий зависимый дочерний объект (isSorted из <List />) к переменной состояния общего родителя (sorted из <Parent />).

При этом вы просто отслеживаете флаг sorted в родительском состоянии (используя useState() hook) и после запуска handleSort() он изменяет этот флаг и выполняет повторную визуализацию зависимых компонентов (<List />):

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>
0 голосов
/ 12 февраля 2020

Передайте данные из состояния в FooComponent и напишите функцию, которая сортирует данные в этом состоянии. Данные будут немедленно обновлены в дочернем компоненте, как только состояние обновится в родительском компоненте, потому что дочерний компонент будет перерисован, как только будет замечено, что данные в родительском компоненте не соответствуют данным, которые он получил ранее. Ниже приведен пример.

import React from 'react'

const FooComponent = ({ fooData }) => (
  <div>
    {fooData}
  </div>
)

export default class Home extends React.Component {

  constructor(props){
    super(props);
    this.state = {
      data: [1, 4, 2, 3]
    }
  }

  sortData() {
    const { data } = this.state;
    this.setState({
      data: data.sort((a, b) => b - a),
    })
  }

  render(){
    const { data } = this.state;
    return (
      <div>
        <button id="myBtn" onClick={() => this.sortData()}>Click Me</button>
        <div className="myClass">
          <FooComponent fooData={data} />
        </div>
      </div>
    )
  }
}
0 голосов
/ 12 февраля 2020

Из вашего вопроса видно, что вы хотите, чтобы дочерний компонент (FooComponent) знал, что кнопка была нажата, чтобы он мог обрабатывать (сортировать) полученные данные.

Существует много подходов к этому. Например, вы можете передать логическое свойство дочернему компоненту, который является флагом для его выполнения сортировки. Таким образом, родительский компонент отслеживает, когда была нажата кнопка, и дочерний компонент просто наблюдает это (возможно, в componentDidUpdate).

Это немного изменится, если вы используете функциональные компоненты, а не компоненты на основе классов, но это дает вам представление.

state = {
   requestSort: false
}   

requestSort = () => {
    this.setState({
        requestSort: true
    }
}

render() {
        return (
          <>
            <button id="myBtn" onClick={this.requestSort}>Click Me</button>

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

В качестве альтернативы, поскольку данные также передаются дочернему компоненту, вы можете parent отсортировать их при нажатии. Это зависит от того, делаете ли вы что-то еще с данными (то есть является ли FooComponent тем, у которого должна быть отсортированная копия данных или нет).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...