Почему мое состояние всегда является значением по умолчанию при вызове внутри Callback? - PullRequest
0 голосов
/ 28 мая 2019

Я не знаю точно, в чем моя проблема. Я использовал какую-то библиотеку. Когда я использую callback и пытаюсь получить состояние Component, состояние всегда является значением по умолчанию.

Пример использования mui-datatables https://github.com/gregnb/mui-datatables

import React, { useState } from 'react'
import MUIDataTable from "mui-datatables";

const columns = [
    {
        name: "name",
        label: "Name",
    },
    {
        name: "company",
        label: "Company",
    },
    {
        name: "city",
        label: "City",
    },
    {
        name: "state",
        label: "State",
    },
];

const data = [
    { name: "Joe James", company: "Test Corp", city: "Yonkers", state: "NY" },
    { name: "John Walsh", company: "Test Corp", city: "Hartford", state: "CT" },
    { name: "Bob Herm", company: "Test Corp", city: "Tampa", state: "FL" },
    { name: "James Houston", company: "Test Corp", city: "Dallas", state: "TX" },
];


const MyComponent = () => {

    const [myState, setMyState] = useState("default value");
    const onRowClick = (rowData, rowMeta) => {
        console.log(myState) //always default value
    }

    const options = {
        onRowClick: onRowClick 
    }
    return (
        <div>
            <MUIDataTable
                title={"Employee List"}
                data={data}
                columns={columns}
                options={options}
            />

            <button onClick={ () => setMyState("State changed")}>Change state</button>
            <p>{myState}</p>

        </div>
    )
}

Сначала я нажимаю button, чтобы изменить MyState, состояние изменилось в теге p. Далее я щелкаю по любой строке, чтобы console MyState. Но это всегда 1015 *. Зачем? Код в CodeSanBox: https://codesandbox.io/s/dreamy-germain-tuylh

Ответы [ 2 ]

0 голосов
/ 28 мая 2019

Это что-то с mui-table. Похоже, он не обрабатывает, если options.rowClick изменилось. Я установил точку останова в MUIDataTable.render(), и она вызывается только один раз. Если указать другое значение options, это не будет выполнено повторно.

Так что, если я добавлю key как

<MUIDataTable
  key={myState}
  ...

, чтобы заставить его быть заново создан вместо обновления - это работает, и State changed отображается в консоли.

Но, возможно, было бы лучше подать вопрос в их github. Или попробуйте самую последнюю версию.

0 голосов
/ 28 мая 2019

Я преобразовал ваш компонент в класс, и теперь он работает, как вы хотели.Ниже вы можете увидеть ошибку, которая происходила, когда вы пытались использовать функциональный компонент.Вероятно, это связано с тем, как построен mui-datatables.Вероятно, для работы требуется компонент класса.

Рабочий пример для CodeSandbox

import React from "react";
import ReactDOM from "react-dom";

import MUIDataTable from "mui-datatables";

const columns = [
  {
    name: "name",
    label: "Name"
  },
  {
    name: "company",
    label: "Company"
  },
  {
    name: "city",
    label: "City"
  },
  {
    name: "state",
    label: "State"
  }
];

const data = [
  { name: "Joe James", company: "Test Corp", city: "Yonkers", state: "NY" },
  { name: "John Walsh", company: "Test Corp", city: "Hartford", state: "CT" },
  { name: "Bob Herm", company: "Test Corp", city: "Tampa", state: "FL" },
  { name: "James Houston", company: "Test Corp", city: "Dallas", state: "TX" }
];

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      myState: "default value"
    };
    this.options = { onRowClick: this.onRowClick };
    this.onRowClick = this.onRowClick.bind(this);
  }

  onRowClick(rowData, rowMeta) {
    console.log(this.state.myState); //always default value
  }

  render() {
    return (
      <div>
        <MUIDataTable
          title={"Employee List"}
          data={data}
          columns={columns}
          options={{ onRowClick: this.onRowClick }}
        />

        <button onClick={() => this.setState({ myState: "State changed" })}>
          Change state
        </button>
        <p>{this.state.myState}</p>
      </div>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<MyComponent />, rootElement);

С вашим кодом я получил следующую ошибку:

Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?

Check the render method of `WithStyles(Tooltip)`.
    in Tooltip (created by WithStyles(Tooltip))
    in WithStyles(Tooltip) (created by t)
    in t (created by l)
    in span (created by l)
    in div (created by l)
    in div (created by ForwardRef(Toolbar))
    in ForwardRef(Toolbar) (created by WithStyles(ForwardRef(Toolbar)))
    in WithStyles(ForwardRef(Toolbar)) (created by l)
    in l (created by t)
    in t (created by WithStyles(t))
    in WithStyles(t) (created by t)
    in t (created by t)
    in div (created by ForwardRef(Paper))
    in ForwardRef(Paper) (created by WithStyles(ForwardRef(Paper)))
    in WithStyles(ForwardRef(Paper)) (created by t)
    in t (created by WithStyles(t))
    in WithStyles(t) (created by MyComponent)
    in div (created by MyComponent)
    in MyComponent
...