Где должно быть определено государство? - PullRequest
0 голосов
/ 12 января 2019

В чем разница между этими двумя конструкциями определения состояния в React?

class ProductsPage extends Component {
  constructor(props) {
    super(props);
    this.state = {
      products: []
    };
  }
  ...
}

и это:

class ProductsPage extends Component {
  state = {
    products: []
  };
  ...
}

Оба они хорошо работают при кодировании в ES6. Тем не менее, нижний, кажется, не работает в машинописном тексте 3. У меня есть следующее:

interface IState {
  products: IProduct[];
}

class ProductsPage extends Component<{}, IState> {
  state = {
    products: []
  };


  public componentDidMount() {
    this.setState({ products });
  }

  public render() {
    return (
      <div className="page-container">
        <ul className="product-list">
          {this.state.products.map(p => (
            <li className="product-list-item" key={p.id}>
              {p.name}
            </li>
          ))}
        </ul>
      </div>
    );
  }
}

и компилятор ts отметил ошибку: идентификатор свойства не существует для типа 'never'

Почему это?

Ответы [ 2 ]

0 голосов
/ 13 января 2019

Как определить состояние для компонента React так же субъективно, как и стили кодирования, которые React продвигает сам. Обычно я иду по очень строгому маршруту, который выглядит следующим образом:

type State = {
    someStateVar: number[];
};

export class MyComponent extends Component<{}, State> {
    public readonly state: State = {
        someStateVar: [],
    };

    public async componentDidMount() {
        // Dynamically fetch data (maybe via axios) and populate the new state
        const data = await axios.get<number[]>(...);
        this.setState({ someStateVar: data });
    }
}

Как видите, я явно отмечаю state как только для чтения, просто убедитесь, что никто не пытается писать напрямую в него (даже если IDE и линтеры могут проверять эти ошибки без мер предосторожности в настоящее время).

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

Кроме того, я в основном сразу определяю значения по умолчанию и заполняю состояние динамическими данными в componentDidMount. Этот подход позволяет сохранить краткость кода, отбросив явное определение конструктора, так как вы должны в любом случае переместить такую ​​инициализацию на componentDidMount и использовать конструктор только для методов привязки, если вы не используете обозначение стрелки члена класса для тех, что в первое место.

0 голосов
/ 12 января 2019

Вторая форма - свойства класса , что является предложением JavaScript на 3-м этапе (т.е. оно еще не является частью языка). Добавление свойств в конструктор - это старый путь ES2015 (называемый максимально минимальными классами).

В вашем случае нет функциональной разницы.

TypeScript требует, чтобы вы объявили поля класса для безопасности типов - отсюда и предупреждение.

...