Превращение реквизита в состояние после инициализации с помощью GetDerivedStateFromProps? - PullRequest
0 голосов
/ 06 октября 2018

У меня есть следующий, супер-простой Компонент:

export default class Editor extends Component {
  constructor(props) {
    super(props);

    this.state = { field: "Some Initial Text" };

    this.handleChangeField = this.handleChangeField.bind(this);
  }

  handleChangeField(e) {
    this.setState({field: e.target.value});
  }

  render() {
    return (
        <div>
          <input type="text" name="word" value={this.state.field} onChange={this.handleChangeField} />
          {this.state.field}
        </div>
    );
  }
}

У него просто есть поле.Поле может быть отредактировано пользователем.В зависимости от того, что пользователь нажимает в одноуровневом компоненте, вышеупомянутый компонент получит реквизит с именем fieldValue, который будет отображаться в поле ввода.Поскольку пользователь должен иметь возможность редактировать это поле ввода, я не могу просто поместить реквизит непосредственно в поле ввода, а использовать состояние.Поэтому я инициализирую состояние компонентов из реквизита.

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

Как бы я решил что-то подобноев Реакте 16.3 с ComponentWillReceiveProps устарела?Я попытался изучить GetDerivedStateFromProps, но не до конца понимаю, как его использовать.

Ответы [ 2 ]

0 голосов
/ 06 октября 2018

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

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

Вот пример:

class Editor extends React.Component {

  state = { field: this.props.defaultValue };

  componentDidUpdate(prevProps) {
    const { defaultValue } = this.props;
    if (prevProps.defaultValue !== defaultValue) {
      this.setState({ field: defaultValue });
    }
  }

  handleChangeField = (e) => {
    this.setState({ field: e.target.value });
  }

  render() {
    return (
      <div>
        <input type="text" name="word" value={this.state.field} onChange={this.handleChangeField} />
        {this.props.defaultValue}
      </div>
    );
  }
}

class App extends React.Component {
  state = { value: 'A default value' }

  handleChange = ({ target }) => this.setState({ value: target.value })

  render() {
    const { value } = this.state;
    return (
      <div>
        <h3>App </h3>
        <input type="text" value={value} onChange={this.handleChange} />
        <hr />
        <h3>Editor</h3>
        <Editor defaultValue={value} />
      </div>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"/>
0 голосов
/ 06 октября 2018

Это очень просто, вот прототип, который должен работать:

export default class Editor extends Component {
  static getDerivedStateFromProps(props, state) {
    // You need to return object that will be used to fill the state, not manipulate the state itself
    return {
      field: state.field
    }
  }

  constructor(props) {
    super(props);

    this.handleChangeField = this.handleChangeField.bind(this);
  }

  handleChangeField(e) {
    this.setState({field: e.target.value});
  }

  render() {
    return (
        <div>
          <input type="text" name="word" value={this.state.field} onChange={this.handleChangeField} />
          {this.state.field}
        </div>
    );
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...