Что такое антипаттерн в reactjs?

Скажем, у меня есть родительский компонент.

Parent.js

class Parent extends React.Component {

  someMethod () {
    LoadDataforChild();
  }

  render() {

    return (
      <div>
        <Child someMethod = {this.someMethod}/>
      </div>
    );
  }
}

export default Parent;

Child.js (Ребенок - это чистый компонент)

class Child extends React.Component {

  componentWillMount() {
    this.props.someMethod();
  }

  render() {
    return (
      <div>
        Hello child
      </div>
    );
  }
}

Я совершенно не знаком с антипаттернами в реакции. Я вызвал родительский метод в Child (чистый компонент). Это антипаттерн? А что такое антипаттерн с точки зрения родительских и дочерних компонентов?

В этом случае дочерний компонент не является чистым компонентом, поскольку вы расширяете React.Component.

Sagiv b.g 03.06.2018 18:31

Прошу прощения, поправьте меня, если я ошибаюсь.

Coder 03.06.2018 18:49
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
2
939
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

В целом антипаттернов не так много, как есть определенный вариант использования для получения данных в родительском элементе - подумайте о нескольких дочерних элементах и ​​т. Д. Но обычно это делается с помощью обратного вызова, например, когда пользователь нажимает кнопку, а не при монтировании. .

В вашем примере было бы разумнее передавать данные непосредственно дочернему элементу в качестве опоры и обрабатывать загрузку данных в родительском событии монтирования.

Обратите внимание, вам, вероятно, следует избегать использования componentWillMount(), поскольку это антипаттерн. Вместо этого используйте componentDidMount(). Прочтите здесь

Ответ принят как подходящий

Распространяя ваш вопрос на анти-шаблоны в reactjs, я хотел бы ответить широко, поскольку я могу основываться на off.docs, статьях и на собственном опыте:

  • не хранить компонент в состоянии компонента или в хранилище (например, в хранилище redux)
    //REDUX REDUCER
    const initialState = {
        isHOCOpened: false,
        child: null
      }

    export default reducer = (state = initialState, {type, content}) => {
        switch (type) {
          case ('openHOC'): {
            const updatedState = {...state};
            updatedState.isHOCOpened = true;
            updatedState.child = content;
            return {
              ...state, ...updatedState
            }
        ...
    }

    //PARENT COMPONENT
    ...some other imports;
    import  ChildElement from './ChildElement';
    export default class ParentElement extends Component {
      ...some code...
      render() {
        const { openHOC, HOCcontent } = this.props;
        return (
          <div onClick = {()=>this.openHOC(<ChildElements/>)}>
            <HOCElement/>
          </div>
    }

    //HIGHER ORDER COMPONENT
    export default const HOC = ({isHOCOpened, child}) => {
      ...some code...
      return (
        <div>
          {isOpened && {children}}
        </div>
      )
    }

Рекомендуемый способ

    ...some other imports;
    import  ChildElement from './ChildElement';
    export default class ParentElement extends Component {
      state = {
        isHOCOpened: false,
      }

      openHOC = () => this.setState({openHOC: true});

      render() {
        return (
          <div onClick = {this.openHOC}>
            {isOpened && <HOCElement/><ChildElement/></HOCElement>}
          </div>
      }
    }

    ...
    export default const HOC = ({children}) => {
      ...some stuff...
      return (
        <div>{children}</div>
      )

Организуйте логику своего приложения, избегая хранения компонентов в состоянии / магазине;

  • не передавайте setState прямо в событиях, как указано выше:
    onClick = {() => {
      //some code
      this.setState({isOpened: true})
    }

Лучше уберите это событие и сохраните его, как в предыдущем примере:

      openHOC = () => {
        //some code
        return this.setState({openHOC: true})
      };

      render() {
        return (
          <div onClick = {this.openHOC}>
            {isOpened && <HOCElement/><ChildElement/></HOCElement>}
          </div>
      }

Это влияет на производительность, поскольку создает функцию каждый раз, но это затрагивает общее понимание JS, только ReactJS. Прочтите статью для более подробного обсуждения это .;

  • не привязывать каждый раз при передаче переменной props, если вы свяжете его со средой, в которой будет выполняться переменная:
    class App extends Component {
      constructor(props) {
        super(props);
        this.state = {
          name: ''
        };
      }

      updateValue(evt) {
        this.setState({
          name: evt.target.value
        });
      }

   render() {
    return (
      <form>
        <input onChange = {this.updateValue.bind(this)} value = {this.state.name} />    
      </form>
    )
      }
    }

вместо этого свяжите все вары в функции конструктора:

    class App extends Component {
      constructor(props) {
        super(props);
        this.state = {
          name: ''
        };
        this.updateValue = this.updateValue.bind(this);
    }
  • не используйте индексы в качестве опоры ключей:
    <ul>
      {liArray.map( (e,i) => <li key = {i}>{e.text}</li>}
    </ul>

Это не совсем антипаттерн, а прямой ошибочный код и неожиданные результаты. Поскольку это много раз было написано в вне документов, React использует ключи для отслеживания изменений в дереве DOM и его перерисовки, поэтому ключи должны быть уникальными, несмотря на то, что индексы изменяют положение его массива; Поместите уникальные реквизиты как идентификаторы или что-то еще {liArray.map(e => <li key = {e.id}>{e.text}</li>}

  • еще один антипаттерн не вычислять значения прямо в setState: setState({value: this.state.counter + passedValue}) Перед вызовом setState выполните:
    updateValue(passedValue) {
       const result = this.state.counter + passedValue;
       setState({value: result})
    }
  • не передавать функцию за setState ожидает выполнения сразу после setState:
      updateValue(value) {
        this.setState({counter: value});
        this.addToCounter(1)
      }

потому что setState является асинхронным Проверь это Передайте его в качестве второго аргумента в setState, чтобы запустить его, когда компонент получит новое состояние:

      updateValue(value) {
        this.setState(
          {counter: value},
          ()=>this.addToCounter(1)
        )
      }
  • и последний не называйте компонент строчной буквой. Реагируйте достаточно умно :), чтобы распознать необходимость передать тег html или компонент реакции: Это не сработает: <mycomponent>content</mycomponent>, но это поможет <Mycomponent>content</MyComponent>. То же самое будет с Кнопка и кнопка;

Почему редукс? было бы лучше реагировать без использования redux.

TomSawyer 22.03.2019 04:39

@TomSawyer Я попытался осветить более сложные ситуации, но просто отреагировал. Этот вопрос задается, чтобы помочь новичкам избежать серьезных ошибок с самого начала, и я попытался охватить больше, чем просто случай приложения.

Alexey Nikonov 26.03.2019 07:26

Другие вопросы по теме