Files
freeCodeCamp/curriculum/challenges/ukrainian/03-front-end-development-libraries/react/change-inline-css-conditionally-based-on-component-state.md
2023-08-16 08:18:51 -07:00

6.4 KiB
Raw Blame History

id, title, challengeType, forumTopicId, dashedName
id title challengeType forumTopicId dashedName
5a24c314108439a4d4036189 Змініть вбудований CSS умовно на основі стану компонента 6 301380 change-inline-css-conditionally-based-on-component-state

--description--

Ви вже бачили декілька застосувань умовного відтворення та використання вбудованих стилів. Розглянемо ще один приклад, який поєднує обидві теми. CSS можна відтворити умовно на основі стану компонента React. Для цього необхідно перевірити умову, та, якщо вона виконана, змінити об’єкт стилів, призначений до елементів JSX в методі відтворення.

Цю парадигму важливо зрозуміти, оскільки вона є різкою зміною від більш традиційного підходу застосування стилів шляхом безпосередньої зміни елементів DOM (що дуже часто зустрічається, наприклад, в jQuery). При такому підході необхідно відстежувати час зміни елементів, а також безпосередньо обробляти керування. Іноді важко відслідковувати зміни, що може зробити UI непередбачуваним. Встановлюючи об’єкт стилю на основі умови, потрібно описувати UI у вигляді функції стану застосунку. Існує чіткий потік інформації, який рухається тільки в одному напрямку. Це найбільш прийнятний метод під час написання застосунків з React.

--instructions--

Редактор коду містить простий керований компонент введення зі стилізованим кордоном. Зробіть цей кордон червоним, якщо користувач вводить понад 15 символів у полі введення. Додайте умову для перевірки та, якщо умова дійсна, встановіть стиль кордону на 3px solid red. Здійсніть перевірку, ввівши текст у поле.

--hints--

Компонент GateKeeper має відтворити елемент div.

assert(
  (function () {
    const mockedComponent = Enzyme.mount(React.createElement(GateKeeper));
    return mockedComponent.find('div').length === 1;
  })()
);

Компонент GateKeeper має ініціалізуватися ключем стану input зі значенням порожнього рядка.

assert(
  (function () {
    const mockedComponent = Enzyme.mount(React.createElement(GateKeeper));
    return mockedComponent.state().input === '';
  })()
);

Компонент GateKeeper має відтворити теги h3 та input.

assert(
  (function () {
    const mockedComponent = Enzyme.mount(React.createElement(GateKeeper));
    return (
      mockedComponent.find('h3').length === 1 &&
      mockedComponent.find('input').length === 1
    );
  })()
);

Спочатку тег input повинен мати властивість border зі значенням 1px solid black.

assert(
  (function () {
    const mockedComponent = Enzyme.mount(React.createElement(GateKeeper));
    return (
      mockedComponent.find('input').props().style.border === '1px solid black'
    );
  })()
);

Якщо введене значення в стані містить понад 15 символів, тег input повинен мати кордон зі значенням 3px solid red.

async () => {
  const waitForIt = (fn) =>
    new Promise((resolve, reject) => setTimeout(() => resolve(fn()), 100));
  const mockedComponent = Enzyme.mount(React.createElement(GateKeeper));
  const simulateChange = (el, value) =>
    el.simulate('change', { target: { value } });
  let initialStyle = mockedComponent.find('input').props().style.border;
  const state_1 = () => {
    mockedComponent.setState({ input: 'this is 15 char' });
    return waitForIt(() => mockedComponent.find('input').props().style.border);
  };
  const state_2 = () => {
    mockedComponent.setState({
      input: 'A very long string longer than 15 characters.'
    });
    return waitForIt(() => mockedComponent.find('input').props().style.border);
  };
  const style_1 = await state_1();
  const style_2 = await state_2();
  assert(
    initialStyle === '1px solid black' &&
      style_1 === '1px solid black' &&
      style_2 === '3px solid red'
  );
};

--seed--

--after-user-code--

ReactDOM.render(<GateKeeper />, document.getElementById('root'))

--seed-contents--

class GateKeeper extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      input: ''
    };
    this.handleChange = this.handleChange.bind(this);
  }
  handleChange(event) {
    this.setState({ input: event.target.value })
  }
  render() {
    let inputStyle = {
      border: '1px solid black'
    };
    // Change code below this line

    // Change code above this line
    return (
      <div>
        <h3>Don't Type Too Much:</h3>
        <input
          type="text"
          style={inputStyle}
          value={this.state.input}
          onChange={this.handleChange} />
      </div>
    );
  }
};

--solutions--

class GateKeeper extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      input: ''
    };
    this.handleChange = this.handleChange.bind(this);
  }
  handleChange(event) {
    this.setState({ input: event.target.value })
  }
  render() {
    let inputStyle = {
      border: '1px solid black'
    };
    if (this.state.input.length > 15) {
      inputStyle.border = '3px solid red';
    };
    return (
      <div>
        <h3>Don't Type Too Much:</h3>
        <input
          type="text"
          style={inputStyle}
          value={this.state.input}
          onChange={this.handleChange} />
      </div>
    );
  }
};