Не удается обновить состояние при нажатии кнопки внутри ячейки таблицы, React Ant Design - PullRequest
0 голосов
/ 11 октября 2018

Я хотел бы обновить состояние, когда ячейка таблицы щелкает.Но событие handleClickis не срабатывает.если я объявляю handleClick вне класса, тогда происходит событие события, но состояние не определено, приходит сообщение.

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

import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { Table, Icon, Switch, Radio, Form, Divider, Button, Modal } from 'antd';

import * as productActions from './../../redux/actions/productActions';

const handleClick = (product) => {
  debugger;
  
  //UNABLE TO UPDATE STATE HERE
  // this.setState({
  //   visibleDeletePopup: true
  // });
  alert(JSON.stringify(product));
}

const columns = [{
  title: 'Name',
  dataIndex: 'name',
  key: 'name',
  width: 150,
  render: text => <a href="javascript:;">{text}</a>,
}, {
  title: 'Full',
  dataIndex: "stockIn['full']",
  key: `stockIn['full'`,
  width: 70,
},
{
  title: 'Half',
  dataIndex: "stockIn['half']",
  key: `stockIn['half'`,
  width: 70,
},
{
  title: 'Quarter',
  dataIndex: "stockIn['quarter']",
  key: `stockIn['quarter'`,
  width: 70,
},
{
  title: '90',
  dataIndex: "stockIn['ninty']",
  key: `stockIn['ninty']`,
  width: 70,
}, {
  title: 'Category',
  dataIndex: 'category',
  key: 'category',
}, {
  title: 'Action',
  key: 'action',
  width: 360,
  render: (text, record) => (<span>
    <button href="javascript:;" onClick={() => handleClick(record)}>Edit-{record.name}</button>
    {/* <Divider type="vertical" />
    <a href="javascript:;">Delete</a>
    <Divider type="vertical" />
    <a href="javascript:;" className="ant-dropdown-link">
      More actions <Icon type="down" />
    </a> */}
  </span>
  ),
}];


const showHeader = true;
let footer = () => 0;
const scroll = { y: 300 };
const pagination = { position: 'bottom' };


class ProductsPage extends React.Component {
  constructor(props) {
    super(props);
    this.onProductSave = this.onProductSave.bind(this);
    this.onChange = this.onChange.bind(this);

    this.state = {
      bordered: true,
      loading: false,
      pagination,
      size: 'small',
      expandedRowRender,
      title: title,
      showHeader,
      footer,
      rowSelection: {},
      hasData: true,
    };

    //Popup and submit button
    this.state.buttonSubmitLoader = false;
    this.state.visibleDeletePopup = false;
  }


  handleClick = (product) => {
    //UPDATE STATE // how?
  }

  showModal = () => {
    this.setState({
      visibleDeletePopup: true,
    });
  }

  handleOk = () => {
    this.setState({ buttonSubmitLoader: true });
    setTimeout(() => {
      this.setState({ buttonSubmitLoader: false, visibleDeletePopup: false });
    }, 3000);
  }

  handleCancel = () => {
    this.setState({ visibleDeletePopup: false });
  }


  render() {
    const state = this.state;
    return (
      <div>
        <div>
          <Table {...this.state}
            columns={columns}
            dataSource={state.hasData ? this.props.products : null}
            footer={() => this.getFooterDetails(this.props.products)}
            pagination={{ pageSize: 5 }}
          />
        </div>
       
      </div>
    );
  }

  componentDidMount() {
    const props = this.props;
    props.actions.loadProducts();
  }

  courseRow(item, index) {
    return <li key={index}>{item.name}</li>;
  }

  onProductSave(product) {

    this.props.actions.createProduct(product);
    this.setState({
      product: ""
    });
  }

  onChange(e) {
    this.setState({
      product: e.target.value
    });
  }

  getFooterDetails(products) {
    return <label class="text-success">Total Records Count is {products.length}</label>;
  }

}


function mapStateToProps(state, ownProps) {
  //In state.products, product is coming from root reducer, if you change 
  //the name products to abhi_products , then here you need to call products:state.abhi_products 
  return {
    products: state.products
  }
}

function mapDispatchToProps(dispatch) {
  return {
    actions: bindActionCreators(productActions, dispatch)
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(ProductsPage);

   

Ответы [ 3 ]

0 голосов
/ 11 октября 2018

Вы можете объявить переменную столбцов внутри конструктора класса следующим образом:

this.columns = []

, и событие будет (вам необходимо связать handleClick ofcourse):

onClick={() => this.handleClick(record)}

ИЛИвы можете передать объявление столбцов извне, как и вы, и вызвать обработчик события с контекстом класса:

onClick={() => ProductsPage.prototype.handleClick(record)}
0 голосов
/ 13 августа 2019
    enter code here

const getColumns = (handleClick) => { // Note here
  return [
   {
      title: 'Name',
  dataIndex: 'name',
  key: 'name',
  width: 150,
  render: text => <a href="javascript:;">{text}</a>,
}, {
  title: 'Full',
  dataIndex: "stockIn['full']",
  key: `stockIn['full'`,
  width: 70,
},
{
  title: 'Half',
  dataIndex: "stockIn['half']",
  key: `stockIn['half'`,
  width: 70,
},
{
  title: 'Quarter',
  dataIndex: "stockIn['quarter']",
  key: `stockIn['quarter'`,
  width: 70,
},
{
  title: '90',
  dataIndex: "stockIn['ninty']",
  key: `stockIn['ninty']`,
  width: 70,
}, {
  title: 'Category',
  dataIndex: 'category',
  key: 'category',
}, {
  title: 'Action',
  key: 'action',
  width: 360,
  render: (text, record) => (<span>
    <button href="javascript:;" onClick={() => handleClick(record)}>Edit-{record.name}</button>
    {/* <Divider type="vertical" />
    <a href="javascript:;">Delete</a>
    <Divider type="vertical" />
    <a href="javascript:;" className="ant-dropdown-link">
      More actions <Icon type="down" />
    </a> */}
  </span>
  ),
}]
}

Тогда внутри вашего компонента

 <Table {...this.state}
    columns={getColumns(this.handleClick)} // and Here
    dataSource={state.hasData ? this.props.products : null}
    footer={() => this.getFooterDetails(this.props.products)}
    pagination={{ pageSize: 5 }}
   />
0 голосов
/ 11 октября 2018

setState будет работать только внутри компонента.Если вы хотите сделать setState в объявленной функции, и вы хотите сделать setState, тогда вы должны передать этот контекст функции.

Ниже будет работать внутри компонента

  handleClick = product => {
      this.setState({
         visibleDeletePopup: true
     });
  }

Обновление:

Весь код компонента может быть исправлен следующим образом

import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { Table, Icon, Switch, Radio, Form, Divider, Button, Modal } from 'antd';

import * as productActions from './../../redux/actions/productActions';


let footer = () => 0;


class ProductsPage extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      bordered: true,
      loading: false,
      pagination: { position: 'bottom' },
      size: 'small',
      expandedRowRender,
      title: title,
      showHeader: true,
      footer,
      rowSelection: {},
      hasData: true,
    };

     handleClick = product => {
        this.setState({
           visibleDeletePopup: true
       });
    }
    //Popup and submit button
    this.state.buttonSubmitLoader = false; // never mutate state like this instead use setState method
    this.state.visibleDeletePopup = false;
  }

  showModal = () => {
    this.setState({
      visibleDeletePopup: true,
    });
  }

  handleOk = () => {
    this.setState({ buttonSubmitLoader: true });
    setTimeout(() => {
      this.setState({ buttonSubmitLoader: false, visibleDeletePopup: false });
    }, 3000);
  }

  handleCancel = () => {
    this.setState({ visibleDeletePopup: false });
  }

  componentDidMount() {
    const props = this.props;
    props.actions.loadProducts();
  }

  courseRow = (item, index) => {
    return <li key={index}>{item.name}</li>;
  }

  onProductSave = product => {
    this.props.actions.createProduct(product);
    this.setState({
      product: ""
    });
  }

  onChange = e => {
    this.setState({
      product: e.target.value
    });
  }

  getFooterDetails = products => {
    return <label class="text-success">Total Records Count is {products.length}</label>;
  }


  render() {
    const { hasData } = this.state;
    const { products } = this.props;
    const columns = [{
      title: 'Name',
      dataIndex: 'name',
      key: 'name',
      width: 150,
      render: text => <a href="javascript:;">{text}</a>,
    }, {
      title: 'Full',
      dataIndex: "stockIn['full']",
      key: `stockIn['full'`,
      width: 70,
    },
    {
      title: 'Half',
      dataIndex: "stockIn['half']",
      key: `stockIn['half'`,
      width: 70,
    },
    {
      title: 'Quarter',
      dataIndex: "stockIn['quarter']",
      key: `stockIn['quarter'`,
      width: 70,
    },
    {
      title: '90',
      dataIndex: "stockIn['ninty']",
      key: `stockIn['ninty']`,
      width: 70,
    }, {
      title: 'Category',
      dataIndex: 'category',
      key: 'category',
    }, {
      title: 'Action',
      key: 'action',
      width: 360,
      render: (text, record) => (<span>
        <button href="javascript:;" onClick={() => this.handleClick(record)}>Edit-{record.name}</button>
      </span>
      ),
    }];
    return (
      <div>
        <div>
          <Table {...this.state}
            columns={columns}
            dataSource={hasData ? products : null}
            footer={() => this.getFooterDetails(products)}
            pagination={{ pageSize: 5 }}
          />
        </div>
      </div>
    );
  }
}


const mapStateToProps = (state, ownProps) => {
  //In state.products, product is coming from root reducer, if you change 
  //the name products to abhi_products , then here you need to call products:state.abhi_products 
  return {
    products: state.products
  }
}

const mapDispatchToProps = dispatch => {
  return {
    actions: bindActionCreators(productActions, dispatch)
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(ProductsPage);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...