Передача состояния из дочернего компонента в другой дочерний компонент, содержащийся в родительском компоненте - PullRequest
1 голос
/ 09 мая 2019

У меня есть дочерний функциональный компонент «Дисплей». Который содержит две кнопки. Кнопки переключают состояние между истиной или ложью.

Я хочу передать это логическое значение обратно в родительский контейнер (компонент).

Затем я хочу передать это логическое значение другому дочернему функциональному компоненту с именем 'DisplayTitle'. Основываясь на логическом значении, я хочу просто обновить строку, которая отображается в функциональном компоненте.

Я немного новичок в этом. Должен ли я использовать избыточный или есть более простой способ сделать это? Спасибо

Еще не

Дочерний компонент «Показать»:

import * as React from 'react';

import Button from 'react-bootstrap/Button';
import Col from 'react-bootstrap/col';

interface Props {
    buttonOneLabel: string;
    buttonTwoLabel: string;
}

const Display = ({
    buttonOneLabel,
    buttonTwoLabel,
}: Props) => {
    const [state, setVariant] = React.useState({ status: true });

    return (
        <>
            <Col md="auto">
              <Button
              onClick={() => setVariant({ status: true })}
              variant={state.status ? 'primary' : 'outline-primary'}
              >
              {buttonOneLabel}
              </Button>
              <Button
              onClick={() => setVariant({ status: false })}
              variant={state.status ? 'outline-primary' : 'primary'}
              >
              {buttonTwoLabel}
              </Button>
            </Col>
        </>
    );
};

export default Display;

дочерний компонент 'DisplayTitles':

import * as React from 'react';

import Col from 'react-bootstrap/col';

interface Props {
    title: string;
}

const DisplayTitles = ({
    title,
}: Props) => (
    <>
        <Col>
          <h3>{title}</h3>
        </Col>
    </>
);

export default DisplayTitles;

Родительский компонент

import * as React from 'react';

import Jumbotron from 'react-bootstrap/Jumbotron';
import Container from 'react-bootstrap/Container';
import Row from 'react-bootstrap/row';

import Title from './Title';
import SearchBy from './SearchBy';
import QuickSearch from './QuickSearch';
import Dates from './Dates';
import Display from './Display';
import DisplayTitle from './DisplayTitle';
import RunReport from './RunReport';
import AdvancedSearch from './AdvancedSearch';
import Options from './Options';

const Header = () => (
  <div className="daily-sales-header">
    <Jumbotron>
      <Container fluid>
        <Title
          title="Daily Sales"
          subTitle="(Single Page)"
        />
        <Row>
          <SearchBy
            colClass="search-by-col"
            buttonId="search-by-button"
            buttonLabel="Search by"
          />
          <QuickSearch
            buttonLabel="Quick Search"
            eleClass="quick-search"
            eleIdBtn="quick-search-button"
          />
          <Dates
            fromClass="from-date"
            fromLabel="From"
            toClass="to-date"
            toLabel="To"
          />
          <Display
            buttonOneLabel="Department"
            buttonTwoLabel="Sub-Department"
            onSelectLanguage={handleVari}
          />
          <RunReport
            buttonLabel="Run Report"
          />
        </Row>
        <Row>
          <AdvancedSearch
            buttonClass="adv-search-btn pull-right"
            buttonLabel="Advanced Search"
          />
        </Row>
      </Container>
    </Jumbotron>
    <Row>
      <DisplayTitle
        title="Department Sales"
      />
      <Options />
    </Row>
  </div>
);

export default Header;

1 Ответ

1 голос
/ 09 мая 2019

Поднятие состояния является наиболее простым подходом здесь.

Родительский компонент будет хранить состояние для всех дочерних компонентов и передавать 1. Значения как реквизит 2. Обратные вызовы, чтобы дети могли изменять значения

Пример (не проверено, используйте только как подсказку)

const Header = () => {
    const [state, setVariant] = React.useState({ status: true });

    return <div className="daily-sales-header">
        /* ... */
        <Display
            uttonOneLabel="Department"
            buttonTwoLabel="Sub-Department"
            onSelectLanguage={handleVari}
            setVariant={setVariant.bind(this)}
            status={state.status}
      />
      /* ... */
  <DisplayTitle
    title="Department Sales"
    status={state.status}
  />
  <Options />
</Row>
</div>
}

Компонент отображения будет

import * as React from 'react';

import Button from 'react-bootstrap/Button';
import Col from 'react-bootstrap/col';

interface Props {
    buttonOneLabel: string;
    buttonTwoLabel: string;
    status: boolean;
    setVariant: (status: {status: boolean}) => void;
}

const Display = ({
    buttonOneLabel,
    buttonTwoLabel,
    status,
    setVariant
}: Props) => {
return (
    <>
        <Col md="auto">
          <Button
          onClick={setVariant.bind(this, { status: true })}
          variant={status ? 'primary' : 'outline-primary'}
          >
          {buttonOneLabel}
          </Button>
          <Button
          onClick={setVariant.bind(this, { status: false })}
          variant={status ? 'outline-primary' : 'primary'}
          >
          {buttonTwoLabel}
          </Button>
        </Col>
    </>
    );
};

export default Display;

Заголовки дисплея будут

// ...
interface Props {
    title: string;
    status: boolean;
}

const DisplayTitles = ({
    title,
    status
}: Props) => (
    <>
        <Col>
             <h3>{title}</h3>
             <h3>{status}</h3>
        </Col>
    </>
);
// ...

В результате при нажатии кнопки в компоненте Display будет вызван setVariant из родительского компонента. Он обновляет status в родительском объекте, который будет немедленно распространяться как реквизит как Display, так и DisplayTitles

.
...