web-dev-qa-db-ja.com

ボタンを使用して、React

これの言い方がわかりません。私はReactを学習していて、フェッチを介してデータをReact-Tableにロードしています。React-Tableとカスタムのプレーンなdivとテーブルだけを使用してみました。

A、B、C、D ... Zのアルファベットのタッチボタンを作成します。これらのボタンは、ボタンにある文字のフィルターを呼び出す必要があります。たとえば、ボタンは次のようになります。

// In Directory.js
class FilterButtons extends React.Component {

alphaFilter(e) {
  console.log(e.target.id);
  // somehow filter the react table
}

render() {

 return (
    <div>
       <button onClick={this.alphaFilter} id="A" className="letter">A</button>
       <button onClick={this.alphaFilter} id="B" className="letter">B</button>
       <button onClick={this.alphaFilter} id="C" className="letter">C</button>
    </div>
  );
 }
}

const BottomMenu = props => (
  <div className="btm-menu">
  <div className="toprow">
  <div className="filter-keys">
    <FilterButtons />
  </div>
</div>
</div>
);

// BottomMenuが含まれるDirectory extends Componentsクラスのクラスがあります

// React Tableを含むDataGrid.jsもそこにあります

class DataGrid extends React.Component {
  constructor() {
    super();
    this.state = {
      data: [],
    };
  }

  componentWillMount() {

    fetch('http://localhost:3000/rooms.json').then((results) => results.json()).then((data) => {
        console.log(data.room);

        this.setState({
          data: data.room
        })
      })
  }

  render() {
    const { data } = this.state;
    return (
      <div>
        <ReactTable
          data={data}
          filterable
          defaultFilterMethod={(filter, row) =>
            String(row[filter.id]) === filter.value}
          columns={[
                {
                  Header: "Name",
                  accessor: "dName",
                  filterMethod: (filter, row) =>
                    row[filter.id].startsWith(filter.value)
                },
                {
                  Header: "Department",
                  accessor: "dDept"
                },
                {
                  Header: "Room",
                  accessor: "dRoom"
                },
                {
                  Header: "Map",
                  accessor: "dRoom",
                  id: "over",
                }

              ]
            }

          defaultPageSize={14}
          className="-striped -highlight"
        />
        <br />

      </div>
    );
  }
}

export default DataGrid; 

この時点で、A、B、Cのいずれかの文字のボタンクリックでReactテーブルをフィルターに掛けるために何をすべきかわかりません。常にある入力フィールドオプションは必要ありません。ユーザーにはキーボードがなく、タッチするだけなので、ボタンだけが欲しいので使用しました。

基本的に、Reactテーブル、またはフィルターに返される文字が付いたボタンをクリックすることでフィルターできる任意のテーブル。JQueryを使用している場合、ボタンクリックを使用してフィルターします。私はまだReactのすべての詳細を学び、これを行う方法を学習していません。また、外部ボタンを使用してソートしたいのですが、うまくいけばもっと簡単になるはずです。

ありがとう。このすべてが意味をなさない場合は申し訳ありませんが、私はそれをレイアウトしようとしています。繰り返しになりますが、キーボードはありません。タッチスクリーンにタッチするだけなので、入力フィールドは機能しません。

5
donlaur

React-Tableフィルターを外部からボタンで制御するには、 Controlled Table の例をご覧ください。次に、テーブルコンポーネントは制御されたコンポーネントになります

そこで、テーブルフィルターの状態を外部で設定し、両方のプロップを使用できます。

<ReactTable  ...(your other props)
        filtered={this.state.filtered}
        onFilteredChange={filtered => this.setState({ filtered })}
 />

filteredプロップは状態の変化を監視します。たとえば、文字ボタンを使用して値を更新するときはいつでも、.

this.setState({filtered: { id: "dName", value: "A"}})

テーブルのフィルターが更新されます。また、onFilteredChangeは逆方向に機能する必要があります。つまり、react-tableの埋め込みフィルタリングはローカル状態を更新できます。これを監視して、DataGridコンポーネント内でその値を使用できるようにします。

もう1つのオプションは、ローカル状態の使用を避け、それをreduxに実装することです。コンポーネントにぶら下がっている状態が最終的にエラーの原因になり、デバッグの複雑さが増しているためです。

更新-詳細については、質問の所有者のコメントに従って:

FilterButtonsとDataGridを一緒に使用するために、FilterButtonsとDataGridの両方をカプセル化するコンテナーコンポーネントを定義できます。コンテナコンポーネントは共有状態を保持し、フィルタリング機能は状態機能で動作します。ただし、データはデータグリッド内に残ります。

class DataGridWithFilter extends React.Component {

// you need constructor() for binding alphaFilter to this. 
// otherwise it cannot call this.setState
constructor(props) {
   super(props);
   this.alphaFilter = this.alphaFilter.bind(this);
}

// personally i do not use ids for passing data. 
// therefore introduced the l parameter for the letter
alphaFilter(e,l) {
  console.log(e.target.id);
  this.setState({filtered: { id: "dName", value: l}});
}

 render(){
   return <div>
      <DataGrid filtered={this.state.filtered} 
                filterFunc={this.alphaFilter}
      </DataGrid>
      <BottomMenu filtered={this.state.filtered}
                  filterFunc={this.alphaFilter} />
   </div>
 }
}

また、この上記のものは、BottomMenuおよびFilterButtonsコンポーネント内からprop filterFuncを使用する必要があります。

class FilterButtons extends React.Component {
render() {
 const {props} =  this;
 return (
    <div>
       <button onClick={(e) => props.filterFunc(e, "A")} id="A" className="letter">A</button>
       <button onClick={(e) => props.filterFunc(e, "B")} id="B" className="letter">B</button>
       <button onClick={(e) => props.filterFunc(e, "C")} id="C" className="letter">C</button>
    </div>
  );
 }
}

const BottomMenu = props => (
  <div className="btm-menu">
  <div className="toprow">
  <div className="filter-keys">
    <FilterButtons filterFunc = {props.filterFunc} />
  </div>
</div>
</div>
); 



class DataGrid extends React.Component {
  constructor() {
    super();
    this.state = {
      data: [],
    };
  }

  componentWillMount() {

    fetch('http://localhost:3000/rooms.json').then((results) => results.json()).then((data) => {
        console.log(data.room);

        this.setState({
          data: data.room
        })
      })
  }

  render() {
    const { data } = this.state;
    return (
      <div>
        <ReactTable
          data={data}
          filterable
          defaultFilterMethod={(filter, row) =>
            String(row[filter.id]) === filter.value}
          columns={[
                {
                  Header: "Name",
                  accessor: "dName",
                  filterMethod: (filter, row) =>
                    row[filter.id].startsWith(filter.value)
                },
                {
                  Header: "Department",
                  accessor: "dDept"
                },
                {
                  Header: "Room",
                  accessor: "dRoom"
                },
                {
                  Header: "Map",
                  accessor: "dRoom",
                  id: "over",
                }

              ]
            }

          defaultPageSize={14}
          className="-striped -highlight"
          filtered = {this.props.filtered}
          onFilteredChange = {filtered => this.props.filterFunc({filtered})}
        />
        <br />
       </div>
    );
  }
}

私はタイプミスなどをチェックしていませんが、これはうまくいくはずです。

4
mcku

Reactでは、状態が変化したときにコンポーネントを更新できます。トリガーする唯一の方法は、this.setState()を使用することです

だから私は自分の状態オブジェクトを次のように変更します:

_state = {
  date: [],
  filter: ""
};
_

ここに新しいファイルがあります:

_// In Directory.js
class FilterButtons extends React.Component {

alphaFilter = (Word) => {
  this.setState({
    filter: Word
  });
};

render() {

 return (
    <div>
       <button onClick={() => this.alphaFilter("A")} id="A" className="letter">A</button>
       <button onClick={() => this.alphaFilter("B")} id="B" className="letter">B</button>
       <button onClick={() => this.alphaFilter("C")} id="C" className="letter">C</button>
    </div>
  );
 }
}

const BottomMenu = props => (
  <div className="btm-menu">
  <div className="toprow">
  <div className="filter-keys">
    <FilterButtons />
  </div>
</div>
</div>
);
_

alphaFilter()を呼び出した直後に、コンポーネントが更新されます。フィルター関数をその中に配置すると、期待どおりに表示されます。したがって、配列の.map()関数を選択します。 filter()を使用するか、map()のデータを比較してから戻ることができます

2
Khun