Как я могу передать состояние в метод рендеринга Tab в семантической реакции пользовательского интерфейса? - PullRequest
0 голосов
/ 29 марта 2019

Я использую Tab от SUIR Я пытаюсь передать некоторые данные состояния в одну из «панелей» и использовать модуль <Dropdown> для рендеринга этих данных состояния. Нужно ли передавать через реквизит или что-то еще?

Я хочу сделать выпадающий список, специфичный для Tab 2. Мне просто интересно, как передать данные состояния в метод рендеринга панелей. Я подумал, может быть, переместить метод рендеринга из panes = [{},{},{}] и поместить его в render() из App. Я не уверен, что лучший подход здесь.

Codesandbox кода ниже.

const panes = [
  { menuItem: "Tab 1", render: () => <Tab.Pane>Tab 1 Content</Tab.Pane> },
  { menuItem: "Tab 2", render: () => <Tab.Pane>Tab 2 Content</Tab.Pane> },
  { menuItem: "Tab 3", render: () => <Tab.Pane>Tab 3 Content</Tab.Pane> }
];

const MockAdapter = require("axios-mock-adapter");
const mock = new MockAdapter(axios);

mock.onGet("/dataschemas").reply(200, {
  data: [
    {
      id: "2",
      selfUri: "/dataschemas/2",
      type: "DataSchema",
      name: "Book Catalog"
    },
    {
      id: "3",
      selfUri: "/dataschemas/3",
      type: "DataSchema",
      name: "Business Articles"
    }
  ]
});

class App extends Component {
  constructor(props) {
    super(props);
    this.state = { activeIndex: 1, dataschemas: [], dataSchemaName: "" };
  }

  handleRangeChange = e => this.setState({ activeIndex: e.target.value });
  handleTabChange = (e, { activeIndex }) => this.setState({ activeIndex });

  async componentDidMount() {
    await this.getSchemas();
  }

  getSchemas = async () => {
    try {
      const { data } = await axios.get("/dataschemas");
      console.log(data);
      const dataschemas = data.data;

      this.setState({ dataschemas: dataschemas });

      console.log("This is the dataschema list:", dataschemas);
    } catch (error) {
      console.error(Error(`Error fetching results list: ${error.message}`));
    }
  };

  handleSchemaChange = e => {
    //handle data schema dropdown change
  };

  // Example of dropdown using dataschemas state

  render() {
    const { activeIndex, dataschemas, dataSchemaName } = this.state;

    return (
      <div>
        <div>activeIndex: {activeIndex}</div>
        <input
          type="range"
          max="2"
          value={activeIndex}
          onChange={this.handleRangeChange}
        />
        <Tab
          panes={panes}
          activeIndex={activeIndex}
          onTabChange={this.handleTabChange}
        />
        <Dropdown
          placeholder="Select data schema"
          scrolling
          clearable
          fluid
          selection
          search
          noResultsMessage="Try a different Search"
          multiple={false}
          options={dataschemas.map(schema => {
            return {
              key: schema.id,
              text: schema.name,
              value: schema.name
            };
          })}
          header="PLEASE SELECT A DATASCHEMA"
          value={dataSchemaName}
          onChange={this.handleSchemaChange}
          required
        />
      </div>
    );
  }
}

1 Ответ

1 голос
/ 29 марта 2019

Например, я могу подумать о следующих решениях:

  1. Глядя на ваш макет, я думаю, что нет необходимости передавать состояние методам рендеринга панелей, поскольку у вас есть компонент Dropdown вне его,Таким образом, вы можете просто определить параметры Dropdown на основе значения activeIndex.
  2. Если вы хотите переместить Dropdown компонент внутри содержимого вкладки (ну, это имеет смысл), тогда вы можете

    • Создайте отдельные компоненты для каждого содержимого вкладки (TabContent1, TabContent2 и т. Д. - можно найти более подходящие названия курсов), а затем создайте panes внутри render() какВы предложили:

      const panes = [
        { menuItem: "Tab 1", render: () => <TabContent1 {/* can pass props here */} /> },
        { menuItem: "Tab 2", render: () => <TabContent2 /> },
        { menuItem: "Tab 3", render: () => <TabContent3 /> }
      ]
      

      И вы можете дополнительно передать некоторые реквизиты этим компонентам, если хотите.Теперь, если содержимое содержимого вкладок очень похоже, вы можете создать один общий TabContent компонент и просто передать туда реквизиты, которые будут отличаться от dropdownOptions={...}

    • То же, что и в предыдущем примере,но вместо создания нового компонента (если вы думаете, что это слишком много суеты) просто создайте отдельный метод renderTabContent() и также создайте panes в render() следующим образом:

      const panes = [
        { menuItem: "Tab 1", render: () => this.renderTabContent(
          /* can pass something here as well */
        )},
        { menuItem: "Tab 2", render: () => this.renderTabContent() },
        { menuItem: "Tab 3", render: () => this.renderTabContent() }
      ]
      

      Опять же, вы можете передатьчто-то в этом методе, например dropdownOptions, чтобы каждый из них возвращал разное содержимое.Или вы можете создать разные renderTabContent1, renderTabContent2 и т. Д. Для каждой вкладки.Внутри этих методов вы можете легко получить доступ к this.state

Это пример CodeSandbox с решением № 2.Я создал только один Tab2Content компонент, но я верю, что вы сможете понять идею и реализовать другие компоненты ?

...